- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(对于不使用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/
我们使用 C# 和 BinaryFormatter 使用 varBinary 类型将字符串值存储在数据库中。我们转换为字节数组,然后保存到数据库 public static byte[] ToByte
(对于不使用Delphi的读者:虽然下面是用Delphi编码来表达的,但我的实际技术问题不是Delphi特定的,而是关于如何找出Sql Server如何“理解”提交给它的 TransactSql 批处
数据库项目构建失败。错误详细信息: Error: MSB4018: The "SqlBuildTask" task failed unexpectedly. System.IO.FileNotFoun
好像ScriptDom具有复杂的架构。由于没有关于 ScriptDom 的文档,您知道如何使用 ScriptDom 类型生成这样的联合查询吗? SELECT c.Title as ColumnTitl
我是一名优秀的程序员,十分优秀!