0

我正在使用 Delphi XE2 调用返回数据的存储过程。存储过程基本上是:

set nocount on -- ensures that Delphi will see that dataset
...
exec StoredProcThatReturnsData
...
update [table]
update [another table]

当主过程是 T-SQL 过程时,它会在将数据返回给 Delphi之前update完成包括最后语句的主过程的执行。

update当主过程是 CLR 过程时,它会在子过程完成执行时返回数据,并且在我关闭TSQLQueryDelphi 中的对象之前不会运行语句。

Delphi 代码如下所示:

rpt := TSQLQuery.Create(nil);
try
  rpt.MaxBlobSize := -1;
  rpt.SQLConnection := ASqlConnection;
  rpt.SQL.Text := 'exec RunMainProc';
  rpt.Open;
  // do some things that depend on the update statements
  // process the 'rpt' data
finally
  FreeAndNil(rpt);
end;

CLR 过程如下所示:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void RunReport(SqlGuid ReportID, SqlGuid UserID, SqlBoolean ForDownload)
{
  using (SqlConnection con = new SqlConnection("context connection=true"))
  {
    con.Open();
    using (SqlCommand cmd = new SqlCommand())
    {
      cmd.Connection = con;
      cmd.CommandText = "[identical SQL as T-SQL proc]";
      SqlContext.Pipe.ExecuteAndSend(cmd);
    }
  }
}

为什么 T-SQL 过程在返回数据之前完成执行,而 CLR 过程等待运行update语句,直到 Delphi 关闭/销毁rpt查询之后?

4

2 回答 2

1

感谢 Jeroen,我尝试从 Delphi 之外的某个地方运行东西并发现了问题。

当我将 T-SQL 过程转换为 CLR 时,我在子过程中添加了一些调试代码,这使它返回两个数据集而不是一个. 这是导致 CLR 版本的过程在主过程完成执行之前交回数据的第二个待处理数据集。

一旦我删除了调试代码(因此只生成了一个数据集),程序的 T-SQL 和 CLR 版本运行完全相同——主程序在数据返回给 Delphi 之前完成运行。

于 2012-09-28T15:59:28.467 回答
0

您的 SP 是否返回记录?看来ti没有。那么你不应该调用 Open on Query。Open 准备 DataSet 以获取数据行,并且由于请求可以持续很长时间 - 它按需获取它们。当您调用TDataSet.NextTDataSet.Last等时。所以我认为,如果你想在 .Open 之后与 SP 同步,你可以调用rpt.Last

但正确的方法是根本不使用Open而是使用ExecSQL

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/SqlExpr_TSQLQuery_ExecSQL.html

PS:在 C# 中,您调用SqlContext.Pipe.Execute,而不是Open。同样的预期也适用于 Delphi,在某种意义上它是 .Net 和 OLE DB 的模型

于 2012-09-28T10:25:29.073 回答