【问题标题】:How to run a database script file from Delphi?如何从 Delphi 运行数据库脚本文件?
【发布时间】:2011-05-12 23:01:05
【问题描述】:

我想做以下事情。 1) 创建数据库。 2) 创建表、存储过程等时运行脚本(此脚本由 SMS 'generate scripts' 选项创建)

我找到了以下代码:http://www.delphipages.com/forum/showthread.php?t=181685 并将其修改为:

试试

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

edtPassword.Text + ';Persist Security Info=True;User ID=' + edtUser.Text + ';初始目录=master;数据源=' + 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 + ';Persist Security Info=True;User ID=' + edtUser.Text + ';初始目录=' + edtWebDBName.Text + ';数据源=' + edtSe​​rverName.Text; ADOWeb.Connected := true;

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

这一直有效,直到运行脚本文件为止。然后它会生成一个异常:“GO”附近的语法不正确。如果我在新创建的数据库上运行 SMS 中的脚本,那很好。这个问题是否是由于一次运行多个 SQL 命令造成的(脚本本质上是一长串命令/GO 语句?如何解决?

另外,作为奖励,在向它发送脚本之前快速检查新数据库是否真的存在有什么想法吗? (或者如果创建失败会产生异常,就没有必要了吗?)

【问题讨论】:

  • 所有这些答案都有效。我认为对于 SMS 生成的脚本,运行 sqlcmd 是要走的路。我也使用下面的来获取数据库计数。 ADOQuery.SQL.Text := 'SELECT COUNT(*) FROM sys.databases WHERE name='+chr(39)+edtWebDBName.Text+chr(39); ADOQuery.打开;如果 ADOQuery.Fields[0].AsInteger = 0 那么 // DB 不存在

标签: sql-server delphi ado


【解决方案1】:

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;

【讨论】:

  • 这里为什么是-1?有什么合理的理由吗?
  • @daemon_x,别担心 ;),我已经习惯了匿名投票者,不再影响我。
【解决方案2】:

GO 表示仅适用于某些 Microsoft 实用程序的批处理结束,它不是正确的 T-SQL 语句。尝试删除脚本中每个出现的GO,然后执行它。 GO 将在脚本结束时为您执行 ADOQuery.ExecSQL

关于你的第二个问题;你可以使用例如SQL 函数DB_ID 检查您的数据库是否存在(当然,您必须在同一台服务器上)。该函数返回数据库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');

【讨论】:

    【解决方案3】:

    脚本可能包含的不仅仅是 SQL DDL/DML 命令。它们可以包含变量、小代码块、事务管理语句。通常有多个语句,由终止符分隔(分号、Oracle 斜线、MSSQL GO 等,具体取决于您使用的数据库及其脚本语法)。要正确执行脚本,您必须解析输入文件,分离每个命令,并将其正确输入数据库。您可以查找库来执行此操作(有一些,IIRC),或者您可以尝试使用 MS SQL 命令行工具通过它提供脚本。

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多