Генерация SQL с помощью Powershell и Regex

Sep 14 2020

У меня есть следующая структура ddl (язык определения данных) в sql:

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

Поскольку я хочу создать несколько таблиц с этой структурой , отличаются только имена таблиц, ключи и имена полей . Поэтому я хочу использовать сценарий Powershell для сканирования каждого файла в каталоге и создания сценария sql для каждого файла. Сгенерированный скрипт должен выглядеть так:

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) 

Для tablename & table_name_tempdb я использую следующее:

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

Теперь я хочу сделать то же самое с ключами и другими полями. Есть какие-нибудь предложения?

Моя идея состоит в том, чтобы сканировать каждую строку от CREATE TABLE до «)» и добавлять каждое слово, начинающееся с «» и заканчивающееся на «» в списке. Строки перед u_version являются ключами, остальные рассматриваются как поля и строят запрос с ними.

Ответы

1 Graham Sep 14 2020 at 22:51

Вот рабочий пример, основанный на предоставленной информации, который выводит новый SQL.

Я подправил вам SQL (ваша вставка в том виде, как она есть, не удалась). Кроме того, если ваши входные файлы отличаются от вашего примера, выражение необходимо настроить.

Чтение содержимого с помощью -Raw позволяет анализировать весь файл вместе.

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

"@

}