挿入を選択に変換

挿入を選択に変換

次の形式のファイルがあります

INSERT INTO table1(field1,field2,field3) VALUES('values1','value2','value3');
INSERT INTO table1(field1,field2,field3) VALUES('other_values1','other_value2','other_value3');
INSERT INTO table1(field1,field2,field3) VALUES('another_values1','another_value2','another_value3');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,field4) VALUES('table2_values1','table2_value2','table2_value3');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,table2_field4) VALUES('other_table2_values1','other_table2_value2','other_table2_value3');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,table2_field4) VALUES('another_table2_values1','another_table2_value2','another_table2_value3','another_table2_value4');

この出力が欲しい

SELECT * FROM table1 WHERE field1='values1' AND field2='values2' AND field3=='values3';
SELECT * FROM table1 WHERE field1='other_values1' AND field2='other_values2' AND field3=='other_values3';
SELECT * FROM table1 WHERE field1='another_values1' AND field2='another_values2' AND field3=='another_values3';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_values2' AND table2_field3=='table2_values3' AND table2_field4=='table2_values4';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_values2' AND table2_field3=='table2_values3' AND table2_field4=='table2_values4';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_values2' AND table2_field3=='table2_values3' AND table2_field4=='table2_values4';

私がこれまでにしたことは

cat test_inserts |awk -F '[()]' '{print $1 " WHERE "$2 $4}' |sed 's/INSERT INTO /SELECT * FROM /g'

それは私に次のような結果を与えます

SELECT * FROM table1 WHERE field1,field2,field3'values1','value2','value3'
SELECT * FROM table1 WHERE field1,field2,field3'other_values1','other_value2','other_value3'
SELECT * FROM table1 WHERE field1,field2,field3'another_values1','another_value2','another_value3'
SELECT * FROM table2 WHERE table2_field1,table2_field2,table2_field3,field4'table2_values1','table2_value2','table2_value3'
SELECT * FROM table2 WHERE table2_field1,table2_field2,table2_field3,table2_field4'other_table2_values1','other_table2_value2','other_table2_value3'
SELECT * FROM table2 WHERE table2_field1,table2_field2,table2_field3,table2_field4'another_table2_values1','another_table2_value2','another_table2_value3','another_table2_value4'

答え1

複雑AWK解決策:

awk -F'[()]' '{ sub(/INSERT INTO */,"",$1); 
                printf "SELECT * FROM %s WHERE ",$1;
                len=split($2, f, ","); split($4, v, ","); 
                for (i=1; i<=len; i++) printf "%s=%s%s", f[i], v[i], (i==len? ";":" AND ");
                print "" 
              }' test_inserts
  • -F'[()]'- 複雑なフィールド区切り記号
  • sub(/INSERT INTO */,"",$1)INSERT INTO- 最初のフィールドからフレーズを削除します(抽出するにはテーブル名前)
  • printf "SELECT * FROM %s WHERE ",$1- 以下を含むSQL文の先頭を印刷します。テーブル名前
  • split($2, f, ",")- 2番目のフィールドを区切り文字に分割して,フィールドを取得する名前fフィールド名の配列になります)
  • split($4, v, ",")- 4番目のフィールドを区切り文字に分割して,フィールドを取得します。価値vフィールド値の配列になります)

出力:

SELECT * FROM table1 WHERE field1='values1' AND field2='value2' AND field3='value3';
SELECT * FROM table1 WHERE field1='other_values1' AND field2='other_value2' AND field3='other_value3';
SELECT * FROM table1 WHERE field1='another_values1' AND field2='another_value2' AND field3='another_value3';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_value2' AND table2_field3='table2_value3' AND field4=;
SELECT * FROM table2 WHERE table2_field1='other_table2_values1' AND table2_field2='other_table2_value2' AND table2_field3='other_table2_value3' AND table2_field4=;
SELECT * FROM table2 WHERE table2_field1='another_table2_values1' AND table2_field2='another_table2_value2' AND table2_field3='another_table2_value3' AND table2_field4='another_table2_value4';

答え2

このようなものが好きなら、ここにPythonの選択肢があります(awk少なくとも私にとってはもっと冗談ですが、読みやすくなります)。

#!/usr/bin/env python2
# -*- coding: ascii -*-
"""transform_query.py"""

import sys
import re

# Open the data file specified by the user
with open(sys.argv[1], 'r') as query_file:
    for row in query_file.readlines():

        # Regular expression to extract table name, field names, and values from each line
        match = re.search(
            r'^INSERT INTO '
                r'(?P<table>table\d+)\((?P<fields>[\w,]+)\) '
                r'VALUES\((?P<values>[^()]+)\);$',
            row.strip()
        )
        if match:

            # Store the table name (not necessary)
            table = match.group('table')

            # Split the fields string into a list
            fields = match.group('fields').split(',')

            # Split the values string into a list
            values = match.group('values').split(',')

            # Recombine the strings into a SELECT statement
            # and print the result
            print(
                "SELECT * FROM {} WHERE {};".format(
                    table,
                    ' AND '.join(
                        ['='.join([field, value]) for field, value in zip(fields, values)]
                    ),
                )
            )

走る:

python transform_query.py query.sql

出力は次のとおりです。

SELECT * FROM table1 WHERE field1='values1' AND field2='value2' AND field3='value3';
SELECT * FROM table1 WHERE field1='other_values1' AND field2='other_value2' AND field3='other_value3';
SELECT * FROM table1 WHERE field1='another_values1' AND field2='another_value2' AND field3='another_value3';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_value2' AND table2_field3='table2_value3';
SELECT * FROM table2 WHERE table2_field1='other_table2_values1' AND table2_field2='other_table2_value2' AND table2_field3='other_table2_value3';
SELECT * FROM table2 WHERE table2_field1='another_table2_values1' AND table2_field2='another_table2_value2' AND table2_field3='another_table2_value3' AND table2_field4='another_table2_value4';

答え3

説明が必要な場合は、お知らせください。コードに説明を追加します。

必要:

  1. フィールド数と値が一致する必要があります。
  2. フィールド名とフィールド値には、次の文字を含めないでください。,)(;- カンマ、角括弧、セミコロン。

gawk '{
    num = patsplit($3$4, arr, /[^,)(;]+/);
    num /= 2;

    printf("SELECT * FROM %s WHERE ", arr[1]);

    for(i = 2; i <= num; i++) {
        printf("%s=%s", arr[i], arr[num + i]);

        printf (i < num) ? " AND " : ";\n";
    }
}' input.txt

説明する:

次の文字列は、例として選択されました。INSERT INTO table1(field1,field2,field3) VALUES('values1','value2','value3');

  1. num = patsplit($3$4, arr, /[^,)(;]+/);
    • patsplit(s, a, r)- 分割文字列 S配列として正規表現についてアル字型、フィールド数を返します。
    • $3$4-イスラム$3諸国table1(field1,field2,field3)$4したがって、VALUES('values1','value2','value3');接続後に次の文字列を取得しますtable1(field1,field2,field3)VALUES('values1','value2','value3');
    • arr次に正規表現に分割します/[^,)(;]+/。これは、カンマ、角かっこ、セミコロンを除くすべての文字を意味します。今:arr[1]yes table1arr[2]yes field1arr[5]yesVALUESなど。
  2. num /= 2;numこのスクリプトで使用されるアルゴリズムでは、変数の半分が必要です。
  3. printf("SELECT * FROM %s WHERE ", arr[1]);- 印刷された最初の要素arrはテーブル名です。私たちの場合ですtable1
  4. printf("%s=%s", arr[i], arr[num + i]);- アルゴリズム。前半に1つの要素を印刷し、arr後半にその要素を印刷しますarr。つまり、arr[2]arr[6]arr[3]arr[7]arr[4]arr[8]
  5. printf (i < num) ? " AND " : ";\n";- 三項演算子。最後の繰り返しでなければ印刷しAND、そうでなければ印刷します;\n(最後のセミコロンと改行文字)。

入力する(入力した内容に誤りがあり、修正しました。フィールド名とフィールド値の数が一致しません。)

INSERT INTO table1(field1,field2,field3) VALUES('values1','value2','value3');
INSERT INTO table1(field1,field2,field3) VALUES('other_values1','other_value2','other_value3');
INSERT INTO table1(field1,field2,field3) VALUES('another_values1','another_value2','another_value3');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,table2_field4) VALUES('table2_values1','table2_value2','table2_value3','table2_value4');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,table2_field4) VALUES('other_table2_values1','other_table2_value2','other_table2_value3','other_table2_value4');
INSERT INTO table2(table2_field1,table2_field2,table2_field3,table2_field4) VALUES('another_table2_values1','another_table2_value2','another_table2_value3','another_table2_value4');

出力

SELECT * FROM table1 WHERE field1='values1' AND field2='value2' AND field3='value3';
SELECT * FROM table1 WHERE field1='other_values1' AND field2='other_value2' AND field3='other_value3';
SELECT * FROM table1 WHERE field1='another_values1' AND field2='another_value2' AND field3='another_value3';
SELECT * FROM table2 WHERE table2_field1='table2_values1' AND table2_field2='table2_value2' AND table2_field3='table2_value3' AND table2_field4='table2_value4';
SELECT * FROM table2 WHERE table2_field1='other_table2_values1' AND table2_field2='other_table2_value2' AND table2_field3='other_table2_value3' AND table2_field4='other_table2_value4';
SELECT * FROM table2 WHERE table2_field1='another_table2_values1' AND table2_field2='another_table2_value2' AND table2_field3='another_table2_value3' AND table2_field4='another_table2_value4';

関連情報