สร้าง SQL ด้วย Powershell & Regex
ฉันมีโครงสร้าง 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 คือคีย์ส่วนอื่น ๆ ถือเป็นฟิลด์และสร้างคิวรีด้วยคีย์เหล่านั้น
คำตอบ
นี่คือตัวอย่างการทำงานตามข้อมูลที่ให้ไว้ซึ่งเป็นผลลัพธ์ของ 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 '))
"@
}