2011-05-12 60 views
6

我想要做以下事情。 1)創建一個數據庫。 2)時創建表,存儲程序等運行腳本(該腳本由SMS產生「生成腳本」選項)如何從Delphi運行數據庫腳本文件?

我發現以下代碼:http://www.delphipages.com/forum/showthread.php?t=181685 並將其修改成這樣:

嘗試

ADOQuery.ConnectionString := 'Provider=SQLOLEDB.1;Password=' + 

edtPassword.Text + ';持續安全信息= TRUE;用戶ID =' + edtUser.Text + ';初始目錄=主人;數據源=' + edtSe​​rverName.Text;

ADOQuery.SQL.Clear; 
ADOQuery.SQL.Text := 'create DataBase ' + edtWebDBName.Text; 
ADOQuery.ExecSQL; // should check existance of database 
ADOWeb.Connected := false; 
ADOWeb.ConnectionString := 'Provider=SQLOLEDB.1;Password=' + 

edtPassword.Text + ';持續安全信息= TRUE;用戶ID =' + edtUser.Text + ';初始目錄=' + edtWebDBName.Text + ';數據源=' + edtSe​​rverName 。文本; ADOWeb.Connected:= true;

ADOQuery.Connection := ADOWeb; 
ADOQuery.SQL.Clear; 
ADOQuery.SQL.LoadFromFile(edtScriptFileName.Text); 
ADOQuery.ExecSQL; except 

這工作,直到運行腳本文件的點。然後它會產生一個異常:「GO」附近的語法錯誤。如果我在新創建的數據庫上運行SMS中的腳本,那很好。這個問題是由於一次運行多個SQL命令(腳本本質上是一長串命令/ GO語句?如何解決它?)

哦,作爲獎勵,任何關於快速檢查的想法在發送腳本之前查看新數據庫是否真實存在?(或者是否不必要,因爲如果創建失敗,它將生成異常?)

+0

所有這些答案都可以使用。我認爲對於SMS生成的腳本,運行sqlcmd是一種方法。此外,我用下面的數據來獲得數據。 (39)+ edtWebDBName.Text + chr(39);其中,數據庫的名稱是數據庫的名稱。 ADOQuery.Open; if ADOQuery.Fields [0] .AsInteger = 0 then // DB不存在 – Rob 2011-05-13 15:28:58

回答

10

Rob GO語句不被ADO識別,所以您必須在執行前從您的腳本中刪除。

我們檢查數據庫是否存在,您可以執行這樣

select COUNT(*) from sys.databases where name='yourdatabasename' 

檢查查詢這個非常基本的樣本

假設你有一個像這樣

CREATE TABLE Dummy.[dbo].tblUsers(ID INT, UserName VARCHAR(50)) 
GO 
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (1, 'Jill') 
GO 
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (2, 'John') 
GO 
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (3, 'Jack') 
GO 

現在的腳本執行這句話你可以做這樣的事情

const 
//in this case the script is inside of a const string but can be loaded from a file as well 
Script= 
'CREATE TABLE Dummy.[dbo].tblUsers(ID INT, UserName VARCHAR(50)) '+#13#10+ 
'GO '+#13#10+ 
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (1, ''Jill'') '+#13#10+ 
'GO '+#13#10+ 
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (2, ''John'') '+#13#10+ 
'GO '+#13#10+ 
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (3, ''Jack'') '+#13#10+ 
'GO '; 

var 
    DatabaseExist : Boolean; 
    i    : Integer; 
begin 
    try 
    //check the connection 
    if not ADOConnection1.Connected then 
     ADOConnection1.Connected:=True; 
     //make the query to check if the database called Dummy exist 
     ADOQuery1.SQL.Add(Format('select COUNT(*) from sys.databases where name=%s',[QuotedStr('Dummy')])); 
     ADOQuery1.Open; 
     try 
     //get the returned value, if is greater than 0 then exist 
     DatabaseExist:=ADOQuery1.Fields[0].AsInteger>0; 
     finally 
     ADOQuery1.Close; 
     end; 


     if not DatabaseExist then 
     begin 
     //create the database if not exist 
     ADOQuery1.SQL.Text:=Format('Create Database %s',['Dummy']); 
     ADOQuery1.ExecSQL; 
     ADOQuery1.Close; 

     //load the script, remember can be load from a file too 
     ADOQuery1.SQL.Text:=Script; 
     //parse the script to remove the GO statements 
     for i := ADOQuery1.SQL.Count-1 downto 0 do 
      if StartsText('GO',ADOQuery1.SQL[i]) then 
      ADOQuery1.SQL.Delete(i); 
     //execute the script 
     ADOQuery1.ExecSQL; 
     ADOQuery1.Close; 
     end; 
    except 
     on E:Exception do 
     ShowMessage(E.Message); 
    end; 

end; 
+0

爲什麼在這裏?任何明智的理由呢? – 2011-05-14 14:07:55

+0

@daemon_x,別擔心;),我習慣了匿名的選民,不再影響我。 – RRUZ 2011-05-14 14:47:51

4

GO表示僅針對特定Microsoft實用程序的批處理結束不是正確的T-SQL語句,請嘗試刪除腳本中的每個發生的GO然後執行它GO將在腳本結尾爲您執行ADOQuery.ExecSQL

對於你的第二個問題;你可以使用例如SQL函數DB_ID來檢查你的DB是否存在(當然你必須在同一個服務器上)。該函數返回數據庫ID;否則爲NULL,所以如果以下SQL語句返回NULL,那麼數據庫創建失敗。

ADOQuery.SQL.Text := 'SELECT DB_ID(' + edtWebDBName.Text + ')'; 
ADOQuery.Open; 

if ADO_Query.Fields[0].IsNull then 
    ShowMessage('Database creation failed'); 
1

腳本可能包含比SQL DDL/DML命令多得多的內容。它們可以包含變量,小塊代碼,事務管理語句。通常有多個語句,由終止符(分號,Oracle斜線,MSSQL GO等分開,取決於您使用的數據庫及其腳本語法)。要正確執行腳本,您必須解析輸入文件,分隔每個命令,並將其正確提供給數據庫。你可以尋找庫來做到這一點(有一些,IIRC),或者你可以嘗試使用MS SQL命令行工具通過它來提供腳本。