Hasilkan SQL dengan Powershell & Regex

Sep 14 2020

Saya memiliki struktur ddl (Data definition language) berikut di sql:

CREATE TABLE tablename(
 key ...,
 key1 ...,
 u_version ...,
 field1 ...,
 field2 ...
)
CREATE UNIQUE clustered... (key ASC, key1 ASC)

Karena saya ingin membuat banyak tabel dengan struktur itu , hanya nama tabel, kunci dan nama field yang berbeda . Jadi saya ingin menggunakan skrip Powershell untuk memindai setiap file di direktori dan menghasilkan skrip sql untuk setiap file. Skrip yang dihasilkan akan terlihat seperti ini:

INSERT INTO tablename(key, key1, u_version, field1, field2)
SELECT key, key1, field1, field2
FROM tablename_temp t
WHERE NOT EXISTS (SELECT key, key1
                  FROM tablename l
                  WHERE l.key = t.key AND l.key1 = t.key1) 

Untuk tablename & table_name_tempdb, saya menggunakan yang berikut ini:

switch -Regex ( $line ) { '(^\s*create\s+table\s+)(?<tablename>[^(]*)' { $table_name = $matches["tablename"] $table_name_tempdb="${table_name}_tmp"
        break
        }
    }

Sekarang saya ingin melakukan hal yang sama pada kunci dan bidang lainnya. Apakah ada saran?

Ide saya adalah memindai setiap baris dari CREATE TABLE sampai ")" dan menambahkan setiap kata yang dimulai dengan "" dan diakhiri dengan "" dalam daftar. Garis sebelum u_version adalah kunci, yang lain dianggap sebagai bidang dan membuat kueri dengan itu.

Jawaban

1 Graham Sep 14 2020 at 22:51

Berikut adalah contoh kerja, berdasarkan informasi yang diberikan, yang mengeluarkan SQL baru.

Saya men-tweak Anda SQL (penyisipan Anda apa adanya akan gagal). Selain itu, jika file masukan Anda berbeda dari contoh Anda, ekspresi tersebut perlu diubah.

Membaca konten dengan -Raw memungkinkan seluruh file diurai bersama.

dir *.sql  |%{
    $filecontents = Get-Content $_.FullName -Raw

    $matches = [Regex]::Match($filecontents, "CREATE TABLE (?'tablename'[^( ]+)\((\W+(?'key'\w+)\W(?'type'[^,)])+[,)])+(\W+u_version\W([^,)])+[,)])(\W+(?'field'\w+)\W(?'type'[^,)])+[,)])+\W+CREATE UNIQUE")

    $tablename = $matches.Groups["tablename"].Value
    $keys = $matches.Groups["key"].Captures.Value
    $fields = $matches.Groups["field"].Captures.Value


'=================================================================='
@"
INSERT INTO $tablename($($keys -join ','), u_version, $($fields -join ',')) SELECT $($keys -join ','), u_version, $($fields -join ',') FROM $($tablename)_temp t WHERE NOT EXISTS (SELECT 1 FROM $tablename l
                  WHERE $(($keys |% { "l.$_ = t.$_" }) -join ' AND ')) 
                 

"@

}