我遇到了 EXECUTE sp_executesql 的问题并坚持使用它。我的查询如下
DECLARE @TABLE_NAME VARCHAR(5)='#T' DECLARE @TABLE_ID INTEGER=0 DECLARE @QRY NVARCHAR(MAX) ='' DECLARE @TABLE VARCHAR(3) DECLARE CRSR_WAGES CURSOR FOR SELECT Code,Name , ROW_NUMBER() OVER (ORDER BY U_Prrty, DocEntry) Slno, COUNT(Code) OVER (PARTITION BY OBJECT) ColNos FROM [@CCS_WAGE] WHERE U_DISPP = 'Y' AND U_DEDWT='E' OPEN CRSR_WAGES FETCH NEXT FROM CRSR_WAGES INTO @WAGECOD,@WAGE_DESC,@SI_NO,@COL_NOS WHILE @@FETCH_STATUS=0 BEGIN SET @TABLE=@TABLE_NAME+CONVERT(VARCHAR(2),@TABLE_ID) SELECT @TABLE AS 'TABLE' SET @QRY='(SELECT empno, amt AS '+'['+@WAGE_DESC+']' SET @QRY=@QRY+' INTO '+@TABLE SET @QRY=@QRY+' FROM CCS_PYMONTHRESULT WHERE wgcod='''+@WAGECOD+''')' SELECT @QRY EXECUTE sp_executesql @QRY SET @TABLE_ID=@TABLE_ID+1 DECLARE @STAR AS NVARCHAR(50)='SELECT * FROM ' + @TABLE SELECT @STAR EXECUTE sp_executesql @STAR FETCH NEXT FROM CRSR_WAGES INTO @WAGECOD,@WAGE_DESC,@SI_NO,@COL_NOS END CLOSE CRSR_WAGES DEALLOCATE CRSR_WAGES
但问题是当执行此错误消息时,就像这个无效的对象名称'#T0'。无效的对象名称“#T1”。无效的对象名称“#T2”。
假设您引用的临时表存在,那么您的问题是会话范围。标记为 single 的临时表
#
对创建它们的会话可见,它们也称为本地临时表。您遇到的问题是,当您执行一段动态 sql 时,它会在新会话中运行 - 因此该会话无法看到您创建的临时表。
要解决此问题,您可以执行以下三件事之一:
##
因为它们在所有会话中都是可见的sp_executesql
我希望这可以帮助你。
动态 SQL 与调用代码在同一会话中运行。问题不是会话,而是范围。您的动态 SQL 在
sp_executesql
调用中创建临时表,因此创建的 #temp 表仅在该sp_executesql
调用中可见,如 MSDN 中所述:因此,您需要在涵盖创建和使用的范围内保留 #temp 表,例如(还修复了您遇到的 SQL 注入问题并
@WAGECODE
作为参数传递):不用说,这是对#temp表的不必要使用,您可以简单地选择您想要的结果并每天调用ti,不需要#temp表: