gpt4 book ai didi

sql-server - 如果查询中有参数,TADOQuery 临时表就会丢失

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

我有一个 TADOQuery,如果我硬编码“Where 参数”,它会生成一个临时表,它工作正常,但如果我使用 TADO 参数,则下一个查询不知道临时表。

我做错了什么?

我希望我可以简化这个例子,但它就是这样。(SQL 服务器)

    CREATE TABLE brFTNode_Children ( 
pID integer NOT NULL,
cID integer NOT NULL,
primary key (pID, cID)
);

insert into brFTNode_Children values(1,2);
insert into brFTNode_Children values(1,3);
insert into brFTNode_Children values(3,4);
insert into brFTNode_Children values(3,5);
insert into brFTNode_Children values(6,4);
insert into brFTNode_Children values(6,7);

代码(不起作用)

procedure Foo(fDBCon : TADOConnection);
const
CreateTempTable =
'WITH FT_CTE AS( ' +
'SELECT pID, cID FROM brFTNode_Children ' +
'WHERE pID = :TOPID ' +
'UNION ALL ' +
' SELECT e.pID, e.cID FROM brFTNode_Children e ' +
' INNER JOIN FT_CTE ftCTE on (ftCTE.cID = e.pID)) ' +
'SELECT * INTO #ParentChild FROM FT_CTE; ';


GetSQL =
'SELECT pID, cID FROM #ParentChild ORDER BY pID; ';
var
q1 : TADOQuery;
q2 : TADOQuery;

begin
q1 := TADOQuery.Create(nil);
q1.Connection := fDBCon;
q1.SQL.Text := CreateTempTable;
q1.ParamCheck := True;
q1.Parameters.ParamByName('TOPID').DataType := ftInteger;
q1.Parameters.ParamByName('TOPID').Value := 1;
q1.ExecSQL;

q2 := TADOQuery.Create(nil);
q2.Connection := fDBCon;
q2.SQL.Text := GetSQL;
q2.Active := true; //Fails here does not know table #ParentChild
end;

代码 - 使用 SQL 查询中的常量

function TGenerateSolveFile.GetBinaryStream(    topID  : Cardinal;
var bFile: TMemoryStream): Boolean;

const
CreateTempTable =
'WITH FT_CTE AS( ' +
'SELECT pID, cID FROM brFTNode_Children ' +
'WHERE pID = 1 ' + //Changed To a constant
'UNION ALL ' +
' SELECT e.pID, e.cID FROM brFTNode_Children e ' +
' INNER JOIN FT_CTE ftCTE on (ftCTE.cID = e.pID)) ' +
'SELECT * INTO #ParentChild FROM FT_CTE; ';


GetSQL =
'SELECT pID, cID FROM #ParentChild ORDER BY pID; ';
var
q1 : TADOQuery;
q2 : TADOQuery;

begin
q1 := TADOQuery.Create(nil);
q1.Connection := fDBCon;
q1.SQL.Text := CreateTempTable;
// q1.ParamCheck := True;
// q1.Parameters.ParamByName('TOPID').DataType := ftInteger;
// q1.Parameters.ParamByName('TOPID').Value := 1;
q1.ExecSQL;

q2 := TADOQuery.Create(nil);
q2.Connection := fDBCon;
q2.SQL.Text := GetSQL;
q2.Active := true;
end;

最佳答案

参数化查询正在使用 exec sp_executesql,它有自己的 session 。

您将从探查器中获得此信息。

exec sp_executesql N'WITH FT_CTE AS( SELECT pID, cID FROM brFTNode_Children WHERE pID = @P1 UNION ALL   SELECT e.pID, e.cID FROM brFTNode_Children e   INNER JOIN FT_CTE ftCTE on (ftCTE.cID = e.pID)) SELECT *  INTO #ParentChild FROM FT_CTE; 
',N'@P1 int',1

如果您在 SSMS 中执行此操作并随后调用 select * from #ParentChild,您将收到相同的错误。

sp_executesql (Transact-SQL)

sp_executesql has the same behavior as EXECUTE with regard to batches, the scope of names, and database context. The Transact-SQL statement or batch in the sp_executesql @stmt parameter is not compiled until the sp_executesql statement is executed. The contents of @stmt are then compiled and executed as an execution plan separate from the execution plan of the batch that called sp_executesql. The sp_executesql batch cannot reference variables declared in the batch that calls sp_executesql. Local cursors or variables in the sp_executesql batch are not visible to the batch that calls sp_executesql. Changes in database context last only to the end of the sp_executesql statement.

关于sql-server - 如果查询中有参数,TADOQuery 临时表就会丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26550791/

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