表定义:
CREATE TABLE [dbo].[tblTest]( [sysId] [int] IDENTITY(1,1) NOT NULL,[Code] [nvarchar](50) NOT NULL,[Name] [nvarchar](500) NOT NULL,CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED ( [sysId] ASC ) WITH ( PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY]
样本数据:
INSERT INTO tblTest ( Code,Name ) VALUES ( 'a1','name1' )
德尔福代码:
ADOQuery.sql.Text := 'SELECT * FROM tblTest WHERE sysId = :sysId'; AdoQuery.Parameters.Parsesql(ADOQuery.sql.Text,True); AdoQuery.Parameters.ParamByName('sysId').value := -1; AdoQuery.open;
ConnectionString(数据库:MyDb)
Provider=sqlOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=MyDb;Data Source=.
AdoQuery.Parameters.Parsesql(ADOQuery.sql.Text,false);
现在任何人都可以解释一下吗?有副作用吗?
解决方法
当我看到这个问题时,我不知道Parsesql做了什么.我多年来一直在做Delphi / sql Server / ADO开发,从未使用它.我认为这将是学习新事物的机会.
请注意,我运行的所有测试在Delphi 7和Delphi XE5中给出了相同的结果.我仍然很想看到一些在Delphi 7中有效但在Delphi XE5中不起作用的代码.
当您执行AdoQuery.sql.Text:=’…’时,如果连接已设置并打开,您的应用程序将创建参数,并查询数据库服务器以确定其类型.这段代码:
AdoQuery := tAdoQuery . Create(nil); AdoQuery . Connection := AdoConnection; ADOQuery.sql.Text := 'SELECT * FROM tblTest WHERE sysId = :sysId'; aDataType := AdoQuery.Parameters.ParamByName ( 'sysId' ) . DataType; Msg ( 'Parameter type = ' + DataTypeToString ( aDataType ) );
将导致:
Parameter type = ftInteger
注意,DataTypeToString只是我编写的将tDataType转换为字符串的例程.
function DataTypeToString ( const nDataType : tDataType ) : string; begin Result := GetEnumName ( TypeInfo(tDataType),integer (nDataType) ); end;
AdoQuery.Parameters.ParamByName ( 'sysId' ) . Value := -1; AdoQuery . Open;
如果您运行sql事件探查器,您将看到发送到sql Server的查询:
exec sp_executesql N'SELECT * FROM tblTest WHERE sysId = @P1 ',N'@P1 int',-1
请注意,@ P1声明为int.
注意:如果连接字符串中有两个空格,则参数类型将显示为ftUnknown,而@ P1将为smallint类型.本答案的其余部分将假设您具有一个空格的正确连接字符串.
用DoCreate = true调用Parsesql有什么作用?
AdoQuery.Parameters.Parsesql(ADOQuery.sql.Text,True);
它做的第一件事是清除参数列表.在这种情况下,这意味着我们已经拥有的正确类型的参数被销毁.然后Parsesql解析sql并找到参数.它创建一个名为sysID的新tParameter对象,并将其添加到列表中.新参数的类型为ftUnknown.
为什么有人想要这样做?如果未设置查询连接,或者未打开,则这可能非常有用.将为您构建参数列表,之后您可以显式设置其数据类型.
如果您要使用DoCreate = false执行Parsesql,那该怎么办?
AdoQuery.Parameters.Parsesql(ADOQuery.sql.Text,false);
答案是:什么都没有. Parsesql将解析sql,查找参数,它将返回如下字符串:
SELECT * FROM tblTest WHERE sysId = ?
用问号替换参数.它不会对参数列表进行任何更改.由于您的代码对返回的字符串不执行任何操作,因此最终结果是对Parsesql的此调用不做任何更改.