我有一个TADOQuery,如果我硬编码Where参数,它会生成一个tempTable,但是如果我使用TADO参数,下一个查询就不知道临时表了。
我做错了什么?
我希望我能简化这个例子,但它在这里。( Server)
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;发布于 2014-10-24 15:29:50
参数化查询使用的是exec sp_executesql,它有自己的会话。
你会从分析器那里得到这个。
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,您将得到相同的错误。
executesql (Transact-SQL)
sp_executesql在批处理、名称范围和数据库上下文方面与EXECUTE具有相同的行为。sp_executesql@stmt参数中的Transact-SQL语句或批处理在执行sp_executesql语句之前不会编译。然后将@stmt的内容编译并作为一个执行计划执行,该执行计划与名为sp_executesql的批处理的执行计划分开。sp_executesql批处理不能引用在调用sp_executesql的批处理中声明的变量。sp_executesql批处理中的本地游标或变量对调用sp_executesql的批处理不可见。数据库上下文的更改只持续到sp_executesql语句的末尾。
https://stackoverflow.com/questions/26550791
复制相似问题