如何执行可能会也可能不会返回数据的SQL脚本?

时间:2015-11-02 23:47:15

标签: sql sql-server delphi ado

这是一个of an old question of mine的扩展,答案并不是我所要求的。我正在做的是在MS SQL Server数据库上执行SQL脚本。此脚本可能会或可能不会返回任何记录集。问题是ADO组件的工作方式,至少据我所知,我只能明确地请求其中一个。

  • 如果我知道查询会返回数据,我会使用TADOQuery.Open
  • 如果我知道查询不会返回数据,我会使用TADOConnection.Execute
  • 如果我不知道查询是否会返回数据...... ???

如何执行任何查询并读取响应以确定它是否有任何记录集,以便我可以读取该记录集?

我尝试了什么:

  1. 调用TADOQuery.Open,但如果没有记录集则会引发异常
  2. 调用TADOQuery.ExecSql,但永远不会返回任何数据
  3. 调用TADOConnection.Execute,但永远不会返回任何数据
  4. 使用选项3并在例外情况下恢复为选项1,但这是工作的两倍(脚本文件超过38,000行)并且有点讨厌。
  5. 使用TADOCommand.Execute,但不断提出“参数对象定义不正确。提供了不一致或不完整的信息”,创建了一些存储过程(否则在使用TADOConnection.Execute时不会发生)。
  6. 调用TADOConnection.Execute重载,返回_Recordset,但TADOConnection.Errors返回空(我依赖于此)。
  7. 正如一些背景知识,目的是实现类似SQL Server Management Studio中的SQL查询工具。它允许您执行任何SQL脚本,如果它返回任何记录集,它会显示它们,否则它只显示输出消息。我正在处理的工具会在GO语句处自动中断SQL脚本,并分别执行每个单独的块。其中一些块可能会返回数据,而其他块可能不会。很明显我在执行之前无法做出这个决定,所以我正在寻找一种方法来继续执行并观察结果。 TADOConnection.Execute提供了一些有用的信息,包括Errors(或输出消息)。

    截至目前,我唯一的选择是在用户界面中提供一个选项,以允许用户选择要使用的执行类型 - 但这正是我想要消除的。

    修改

    TADOCommand.Execute方法最接近我想要的方法。但是,它在一些脚本上失败,否则使用TADOConnection.Execute完全正常。请参阅上面“我尝试过的内容”中的#5。我几乎写了这个作为我的答案,直到我发现几乎所有事情都发生了这个错误。

    修改

    在下面发布我的答案之后,我开始了解当我使用Errors的其他重载时,Execute属性不再返回任何内容。请参阅上面“我尝试过的内容”中的#6。

    呼叫...

    ADOConnection1.Execute('select * from something', cmdText, []);
    

    ...不会在ADOConnection1.Errors中返回任何内容,而是......

    var
      R: Integer;
    begin
      ADOConnection1.Execute('select * from something', R);
    

    ...确实在ADOConnection1.Errors中返回消息,这是我需要的,但是,它不会返回任何记录集。

1 个答案:

答案 0 :(得分:0)

编辑:不是正确的解决方案

在深入挖掘之后,我终于发现了我的解决方案。答案是使用支持返回记录集的TADOConnection.Execute()重载:

function TADOConnection.Execute(const CommandText: WideString;
  const CommandType: TCommandType = cmdText;
  const ExecuteOptions: TExecuteOptions = []): _Recordset;

然后,只需将生成的_Recordset分配给支持的数据集组件的Recordset属性。

var
  RS: _Recordset;
begin
  RS := ADOConnection1.Execute('select * from something', cmdText, []);
  if Assigned(RS) then begin
    ADODataset1.Recordset:= RS;
    ...
  end;
end;

缺点是您不能使用支持返回RowsAffected的其他重载。此外,使用此Errors的重载版本时,TADOConnection的{​​{1}}属性中不会返回任何内容,而另一个版本会执行此操作。但其他人并没有返回记录集。

相关问题