好的,这是一个卷发。我正在编写一些我没有编写的 Delphi 代码,我遇到了一个非常奇怪的问题。我的存储过程的参数之一是通过 as null
,即使它肯定是被发送的1
。
Delphi 代码使用 TADOQuery 来执行存储过程(匿名):
ADOQuery1.SQL.Text := "exec MyStoredProcedure :Foo,:Bar,:Baz,:Qux,:Smang,:Jimmy";
ADOQuery1.Parameters.ParamByName("Foo").Value := Integer(someFunction());
// other parameters all set similarly
ADOQuery1.ExecSQL;
Integer(SomeFunction())
目前总是返回 1 - 我用调试器检查过。
但是,在我的存储过程中(出于调试目的而更改):
create procedure MyStoredProcedure (
@Foo int, @Bar int, @Baz int,
@Qux int, @Smang int, @Jimmy varchar(20)
) as begin
-- temp debug
if ( @Foo is null ) begin
insert into TempLog values ( "oh crap" )
end
-- do the rest of the stuff here..
end
TempLog
确实以“哦,废话”结尾(附带问题:必须有更好的方法来调试存储的过程:它是什么?)。
以下是分析器的示例跟踪:
exec [MYDB]..sp_procedure_params_rowset N'MyStoredProcedure',1,NULL,NULL
declare @p3 int
set @p3=NULL
exec sp_executesql
N'exec MyStoredProcedure @P1,@P2,@P3,@P4,@P5,@P6',
N'@P1 int OUTPUT,@P2 int,@P3 int,@P4 int,@P5 int,@P6 int',
@p3 output,1,1,1,0,200
select @p3
这对我来说有点奇怪。请注意,它正在使用 @p3和@P3 - 这会导致我的问题吗?
另一个奇怪的事情是,它似乎取决于我使用的 TADOConnection。
该项目是一个 dll,它从另一个应用程序传递了一个 TADOConnection。它使用此连接调用所有存储过程。
如果不使用此连接,我首先这样做:
ConnectionNew := TADOQuery.Create(ConnectionOld.Owner);
ConnectionNew.ConnectionString := ConnectionOld.ConnectionString;
TADOQuery1.Connection := ConnectionNew;
那么问题就不会出现了!这种情况的痕迹是这样的:
exec [MYDB]..sp_procedure_params_rowset N'MyStoredProcedure',1,NULL,NULL
declare @p1 int
set @p1=64
exec sp_prepare @p1 output,
N'@P1 int,@P2 int,@P3 int,@P4 int,@P5 int,@P6 varchar(20)',
N'exec MyStoredProcedure @P1,@P2,@P3,@P4,@P5,@P6',
1
select @p1
SET FMTONLY ON exec sp_execute 64,0,0,0,0,0,' ' SET FMTONLY OFF
exec sp_unprepare 64
SET NO_BROWSETABLE OFF
exec sp_executesql
N'exec MyStoredProcedure @P1,@P2,@P3,@P4,@P5,@P6',
N'@P1 int,@P2 int,@P3 int,@P4 int,@P5 int,@P6 varchar(20)',
1,1,1,3,0,'400.00'
不幸的是,这对 lil ol' 我来说有点过分了。什么样的 TADOConnection 选项可能会影响这一点?
有没有人有任何想法?
编辑: 下面更新(不想再提出这个问题了:P)