【问题标题】:where remains exec query data context?exec 查询数据上下文在哪里?
【发布时间】:2012-01-26 20:37:53
【问题描述】:

我在 sql server 上使用 exec("query_string") 命令。问题是这个命令执行的更改在外面是看不到的。

我的意思是,我尝试在 exec 命令中创建一个带有动态列的临时表,它运行正常,但是当我尝试对创建的表进行选择语句时,我收到一条错误消息,指出该表没有存在。

我知道这是一个上下文问题,我的意思是我如何让 exec 命令像其他 sql 语句一样在相同的上下文中运行???

CREATE TABLE #Test ( TheDate datetime, Harvest int )
INSERT INTO #Test(TheDate, Harvest) VALUES ('2011/10/11', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('2012/10/11', 100)
INSERT INTO #Test(TheDate, Harvest) VALUES ('2011/10/01', 20)
INSERT INTO #Test(TheDate, Harvest) VALUES ('2011/12/11', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('2011/11/11', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('2011/11/12', 150)

DECLARE @listCol2 varchar(max)
SET @listCol2 = 
    (SELECT DISTINCT ('[' + CONVERT(varchar,YEAR(TheDate)) + '-' + RIGHT('0'+CONVERT(varchar,MONTH(TheDate)),2) +'] date,')
     FROM #Test
     ORDER BY ('[' + CONVERT(varchar,YEAR(TheDate)) + '-' + RIGHT('0'+CONVERT(varchar,MONTH(TheDate)),2) +'] date,') ASC
     FOR XML PATH(''))
SET  @listCol2 = LEFT(@listCol2,LEN(@listCol2)-1)
SELECT  @listCol2

EXEC ('CREATE TABLE #Test2 ('+@listCol2+')') 

SELECT * FROM #Test2 --In this line I got this message: the name of the object #Test2 isn't valid, why???

DROP TABLE #Test2

DROP TABLE #Test

谢谢

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    来自MSDN

    在存储过程中创建的本地临时表被删除 存储过程完成时自动执行。

    由于您的 EXEC (...) 实际上是对存储过程的调用(想想sp_executesql),所以当您尝试从中选择时,#Test2 超出范围,因此被丢弃。您必须将 SELECT 放在同一个 EXEC 中:

    EXEC ('CREATE TABLE #Test2 ('+@listCol2+'); SELECT * FROM #Test2');
    

    【讨论】:

    • 感谢您的信息。如果我用这个名称创建一个临时表 ##Test2 它可以工作!!!! :)
    • 当然##Temp2 有效,因为 ei 是一个 global 临时表。但这是不正确的,因为现在两个不同的用户/会话将创建/选择 same 全局临时表,这将导致各种竞争条件和随机崩溃/失败,你会变老尝试调查/修复...
    【解决方案2】:

    您可以有以下选项。

    EXEC ('CREATE TABLE #Test2 ('+@listCol2+'); Select * from #test2') 
    
    
    
    EXEC ('CREATE TABLE ##Test2 ('+@listCol2+')') 
    
    SELECT * FROM ##Test2 --it will not throws the name of the object isn't valid
    
    DROP TABLE ##Test2
    
    
    EXEC ('CREATE TABLE Test2 ('+@listCol2+')') 
    
    SELECT * FROM Test2 --it will not throws the name of the object isn't valid
    
    DROP TABLE Test2
    

    【讨论】:

    • 是的,对我有用的解决方案是##Test2,但是双尖是什么意思????
    • 是的。该表位于数据库服务器上。
    • 它是一个全局表,所有用户都可以访问...不像本地临时变量,其范围是在当前会话中定义的。
    【解决方案3】:

    您的表创建错误,因此不存在。 #test2 表的查询应该是这样的。日期不是一个定义的字段。

    CREATE TABLE #Test2 ([2011-10] datetime,[2011-11] datetime,[2011-12] datetime,[2012-10] datetime)
    

    如果我像这样修改你的 sql 并运行它,我会得到这个错误

    名称 'CREATE TABLE #Test2 ([2011-10] 日期,[2011-11] 日期,[2011-12] date,[2012-10] date)' 不是有效的标识符。

    修改后的代码

    DECLARE @listCol2 varchar(max)
    SET @listCol2 = 
        (SELECT DISTINCT ('[' + CONVERT(varchar,YEAR(TheDate)) + '-' + RIGHT('0'+CONVERT(varchar,MONTH(TheDate)),2) +'] date,')
         FROM #Test
         ORDER BY ('[' + CONVERT(varchar,YEAR(TheDate)) + '-' + RIGHT('0'+CONVERT(varchar,MONTH(TheDate)),2) +'] date,') ASC
         FOR XML PATH(''))
    SET  @listCol2 = LEFT(@listCol2,LEN(@listCol2)-1)
    SELECT  @listCol2
    
    DECLARE @q varchar(4000)
    set @q= 'CREATE TABLE #Test2 ('+@listCol2+')'
    
    exec @q 
    

    【讨论】:

    • 问题仍然会出现,因为在动态查询执行后无法访问#temp2。你能修改你的帖子吗..我不会投反对票的。
    • 这里的问题是#test2没有创建,错误根本没有显示。如果未创建,则您正在查询无效对象。
    • OP 试图在 exec @q 行之后访问#temp,并且在这行代码之后对象变得无效。
    • 不。创建后他永远无法访问它。我更新了我的答案。
    • 日期它是一个有效的数据类型。但是在我用 exec 创建表之后,我尝试进行选择,但失败了
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2022-01-06
    • 2020-12-19
    • 2011-08-22
    • 1970-01-01
    相关资源
    最近更新 更多