Delphi - SQL szkript létrehozása egy tábla soraiból

forráskód letöltése
Az MS SQL szerver Enterprise Manager nevű segédprogramjával lehetőségünk van szkriptet generálni egy adatbázis szerkezetéről. Amikor ezt a szkriptet futtatjuk egy másik számítógépen, akkor automatikusan létrejön az adatbázis, amely azonban egyetlen sort sem tartalmaz. Ebben a példában egy olyan programot készítünk, amely egy megadott tábla soraiból futtatható szkriptet készít. Segítségével ezután nem csak a táblák szerkezetét, hanem tartalmát is átvihetjük egyik gépről a másikra.
Mielőtt elindítaná a példaprogramot, futtassa le a Run_script.cmd állományt. Az Form1-en lévő ADOConnection1 objektum ConnectionString-jét módosítsa úgy, hogy az SQL szerver összes adatbázisa elérhetővé váljon.
Alkalmazásunk és az SQL szerver közti kapcsolatot - a szokásos módon - ADO komponensek segítségével hozzuk létre. A ConnectionString létrehozásánál a megjelenő ablakban úgy állítsuk be a kapcsolatot, hogy nem adunk meg adatbázis nevet. Így lehetővé válik, hogy ugyanazzal a beállítással a szerver összes adatbázisát elérjük.
A szkriptet egy TEXT típusú állományban kell elhelyeznünk. A TEXT formátumból adódóan a nagy mennyiségű adatot tartalmazó Binary, Image, Sql_Variant, valamint VarBinary mezők tartalmával nem tudunk mit kezdeni. Ha a felsorolt típusú mezők valamelyike nagy mennyiségű adatot tartalmaz, a szkript generálása nem alkalmazható.
A feldolgozás elején az eredeti ConnectionString-et elmentjük a DefConString változóba, majd az ADOCOnnection1 objektum segítségével csatlakozunk a felhasználó által megadott adatbázishoz. A feldolgozás végén pedig visszaállítjuk az eredeti ConnectionString-et.
DefConString:=ADOConnection1.ConnectionString;
ADOConnection1.ConnectionString:=DefConString+';'+'Initial Catalog='+Edit1.Text+';';
A megadott táblához az ADOTable1 objektum segítségével kapcsolódunk. A feldolgozás során végig kell mennünk a tábla összes során. Egy adott sor tartalmából el kell készítenünk egy olyan INSERT INTO parancsot, amely az új számítógépen képes korrektül létrehozni a megadott sort. A parancsot az s változó segítségével hozzuk létre.
Először létrehozzuk az INSERT INTO parancs oszloplistáját.
s:='INSERT INTO '+Edit2.Text+'(';
for i:=0 to FieldCount-1 do
  s:=s+' '+Fields[i].FieldName+',';
Ezt követi a VALUES kulcsszó, majd az egyes értékek.
A tábla minden mezőjét AsString-ként olvassuk be. Az INSERT INTO parancsban gondoskodnunk kell az adattípusoknak megfelelő konverziókról.
A tábla oszlopainak típusát az sp_columns tárolt eljárás segítségével kérdezhetjük le. A tárolt eljárást az ADOStoredProc1 objektum segítségével hívjuk meg. Egyetlen paramétert kell használnunk, a tábla nevét.
Minden sorban, egy for ciklus segítségével végig kell mennünk az összes mezőn. A mező típusát az az ADOStoredProc1 eredménytáblájának Type_Name mezőjéből olvashatjuk ki. Az eredménytáblában minden egyes mező külön sort képez. Ez azt jelenti, hogy a tárolt eljárás eredménytáblájában lévő sorok száma megegyezik az ADOTable1 tábla oszlopainak számával.
TypeName:=ADOStoredProc1.FieldByName('Type_Name').AsString;
SQL-ben a sztringeket ’ jel közé kell tennünk. Előfordulhat, hogy egy beolvasott mező tartalmában található ilyen jel. Ez hibát okozna az INSERT parancsban. Ezeket a karaktereket a CHAR függvény segítségével helyettesíteni tudjuk.
t:='';
for j:=1 to Length(DataText) do
  if DataText[j]=#39 then
    t:=t+#39+'+CHAR(39)+'+#39
  else
    t:=t+DataText[j];
DataText:=t;
Feldolgozás során külön eljárást kell alkalmaznunk a következő mezők esetében: bit, money, smallmoney, binary, varbinary, image, timestamp, float, real, datetime, és smalldatetime.
A timestamp típusú mezők értékét nem módosíthatjuk, itt csak NULL értéket használhatunk.
Real és float típus esetében, ha a tizedespont vessző, akkor azt ki kell cserélnünk pontra.
Bit esetében a megjelenítés True és False értékeket ad, míg tárolásra csak az 1 és 0 karaktereket használhatjuk.
Például a money típus esetében, a kiolvasott sztringet konvertálnunk kell.
if TypeName='money' then
  s:=s+' CAST ('+#39+DataText+#39+' AS money),'; 
Image típus esetén a CONVERT függvényt kell használnunk.
if TypeName='image' then
  s:=s+' CONVERT (image, '+#39+DataText+#39+',';
A dátumok kezelésénél problémát okoz az operációs rendszer és az SQL szerver különböző dátumformátuma. Amikor Delphi-ben beolvasunk egy TDateTime-ot, akkor annak formátuma a következő: pl.: 2003.01.01. 10:28:00. Ebből a következő formátumot kell előállítanunk: 2003-01-01 10:28:00.00.
A konvertálást a ConvertDate függvény végzi el.
function ConvertDate(s: String): String;
Bemenő paraméterként a „Delphi formátumú” dátumot kell megadni, eredményként az SQL-ben használható megfelelőjét kapjuk.