Generuj SQL za pomocą PowerShell i Regex

Sep 14 2020

Mam następującą strukturę ddl (język definicji danych) w sql:

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

Ponieważ chcę utworzyć wiele tabel z taką strukturą , tylko nazwy tabel, klucze i nazwy pól są różne . Dlatego chcę użyć skryptu Powershell, aby przeskanować każdy plik w katalogu i wygenerować skrypt sql dla każdego pliku. Wygenerowany skrypt powinien wyglądać następująco:

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) 

W przypadku nazwy tabeli i nazwy_tabeli_tempdb używam następującego:

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

Teraz chcę zrobić to samo z kluczami i innymi polami. Czy są jakieś sugestie?

Moim pomysłem jest przeskanowanie wszystkich linii od CREATE TABLE do „)” i dodanie każdego słowa na liście zaczynającego się od „” i kończącego na „”. Wiersze przed u_version są kluczami, pozostałe są traktowane jako pola i na ich podstawie buduje zapytanie.

Odpowiedzi

1 Graham Sep 14 2020 at 22:51

Oto działający przykład oparty na dostarczonych informacjach, który generuje nowy kod SQL.

Poprawiłem ci SQL (twoja wstawka nie powiodłaby się). Ponadto, jeśli twoje pliki wejściowe różnią się od twojego przykładu, wyrażenie będzie wymagało poprawienia.

Czytanie zawartości za pomocą -Raw pozwala na wspólną analizę całego pliku.

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 ')) 
                 

"@

}