gpt4 book ai didi

sql-server - 获取 TransactSql 批处理中的语句数计数

转载 作者:行者123 更新时间:2023-12-03 00:03:35 24 4
gpt4 key购买 nike

(对于不使用Delphi的读者:虽然下面是用Delphi编码来表达的,但我的实际技术问题不是Delphi特定的,而是关于如何找出Sql Server如何“理解”提交给它的 TransactSql 批处理。“TAdoQuery”是一个 Delphi 类,它基本上包装了 ADO 命令和 RecordSet,并将 TSql 批处理提交到 Sql Server。通常,使用 TAdoQuery,批处理是单个语句,但我的 q特别关注批处理可能包含多个语句的可能性。)

假设我有一个 TAdoQuery,其 Sql.Text 包含一个 TransactSql 批处理,其中包含一个或多个语句 S1[...Sn]。

我想做的是找出不执行批处理是否a)批处理中的第一个(或唯一)语句S1将返回结果集(即使为空)例如,通过它是一个 SELECT 语句或对存储过程或表函数的调用,或其他什么,并且 b)服务器认为批处理中有多少条语句。

Delphi TAdoQuery 的普通用户会知道,只需调用 TAdoQuery.Open 即可测试批处理中的第一个(或唯一一个)语句是否返回结果集,这很简单,但有点困惑。如果是,则它将检索该结果集,但如果不是,则调用 .Open 将引发异常。

所以,我做了这样的事情:

type
TMyDataSet = class(TDataSet);

procedure TForm1.Button1Click(Sender: TObject);
begin
if AdoQuery1.Active then
AdoQuery1.Close;
AdoQuery1.FieldDefs.Clear;
TMyDataSet(AdoQuery1).OpenCursor(True);
AdoQuery1.FieldDefList.Update;
//AdoQuery1.FieldList.Update;
//Listbox1.Items.Assign(AdoQuery1.FieldList);
end;

调用.OpenCursor并将其InfoQuery参数设置为true会导致AdoQuery的FieldDefs要填充iff,其 Sql 中的第一个语句将返回结果集,但是,与调用 .Open 不同,它不会导致执行批处理。

到目前为止,一切都很好。这是我的问题:

如何(通过 AdoQuery 或其他方式)让 Sql Server 告诉我有多少个它认为该批处理包含哪些语句? (我想我可能偶然发现了一种方法(需要进行更多测试),但我对是否有人知道执行此操作的“官方”技术感兴趣。)

顺便说一句,现在我正在通过 Sql Server 的 OleDB 驱动程序使用古董(Sql Server 2000!)服务器。

最佳答案

您可以使用SET SHOWPLAN_ALL函数来分析 SQL Server 中的语句而不是执行查询。请注意,您不能将此功能与 TADOQuery 一起使用,而只能与 TADOCommand 对象一起使用(例如 TADOConnection.Execute)。

测试表:

USE [TestCustomer]

GO
CREATE TABLE [dbo].[Tbl_test](
[Id] [int] NULL,
[col1] [varchar](50) NULL
) ON [PRIMARY]

GO

小演示程序:

program SO27007086;

{$APPTYPE CONSOLE}

uses
ActiveX,
Db,
AdoDb,
SysUtils;

var
DbConn : TADOConnection;

function GetNumberOfStatements(SQLQuery: String): Integer;

var
Rs : _RecordSet;
LastId : Integer;

begin
Result := 0;
LastId := -1;
DbConn.Execute('SET SHOWPLAN_ALL ON');
Rs := DbConn.Execute(SQLQuery, cmdText, []);
while not Rs.EOF do
begin
if Rs.Fields['StmtId'].Value <> LastId then
begin
Inc(Result);
LastId := Rs.Fields['StmtId'].Value;
end;
if Rs.Fields['Parent'].Value = 0 then
Writeln(Rs.Fields['Type'].Value);
Rs.MoveNext;
end;
DbConn.Execute('SET SHOWPLAN_ALL OFF');
end;

begin
try
try
CoInitialize(nil);
DbConn := TADOConnection.Create(nil);
try
DbConn.ConnectionString := 'Provider=SQLOLEDB;Integrated Security=SSPI;Initial Catalog=TestCustomer;Data Source=localhost\SQLEXPRESS;MARS Connection=True;';
DbConn.Connected := True;
Writeln(GetNumberOfStatements('SELECT * FROM Tbl_test'));
Writeln(GetNumberOfStatements('SELECT * FROM Tbl_test DELETE FROM Tbl_test WHERE 1 = 2'));
Writeln(GetNumberOfStatements('SELECT * FROM Tbl_test INSERT INTO Tbl_Test (Id, Col1) VALUES (3, ''c''),(4, ''d'')'#13#10'DELETE FROM Tbl_test WHERE 1 = 2'));
finally
DbConn.Free;
end;
finally
CoUninitialize;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

输出:

SELECT
1
SELECT
DELETE
2
SELECT
INSERT
DELETE
3

关于sql-server - 获取 TransactSql 批处理中的语句数计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27007086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com