首页 文章

检查临时表中是否存在列始终在SQL Server中返回false

提问于
浏览
4

我有以下执行语句创建一个表(使用来自另一个过程的数据),将值插入临时表,添加一个图像列(因为它们不能包含在分组中),然后根据另一个标准更新它临时表(生成的表字段在SSRS报告中使用,因此我需要保留IMAGE数据类型):

EXEC ('SELECT ' + @COL_TO_GROUP_BY + @COL_ADDITONAL + @sColVals + ' INTO
#RESULTS_TABLE from (' + @SQL_STATEMENT + ') A ' + @WHERE_CLAUSE + ' GROUP BY ' +
@COL_TO_GROUP_BY +

' ALTER TABLE #RESULTS_TABLE
ADD IMAGE_DATA IMAGE

IF EXISTS(SELECT * FROM tempdb.INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 
''COLUMN_A'' and TABLE_NAME LIKE ''#RESULTS_TABLE%'')
BEGIN
    UPDATE #RESULTS_TABLE
    SET IMAGE_DATA = FILE_DATA
    FROM #RESULTS_TABLE A, #IMAGE_TABLE B 
    WHERE A.COLUMN_A = B.COLUMN_A
END

SELECT * FROM #RESULTS_TABLE')

问题是无论COLUMN_A是否存在,IMAGE_DATA的列始终为NULL . 有没有其他方法可以将数据导入IMAGE_DATA列?请帮忙!

注意:我不会接受任何结论是问题与其他表中的内容相关的答案,更具体地说,来自WHERE子句 . 我已经做了多次验证,以确保条件可以是真和假(匹配行,没有匹配的行等) . 所以这排除了条件语句 . 谢谢 .

EDIT:

我仍然不完全确定它的确切原因是什么,但我最终创建了一个全局临时表并运行了两个单独的程序,现在它似乎工作正常 . 我不得不接受最符合我自己解决方案的答案 . 所有答案和评论都非常可行 . 谢谢!

3 回答

  • 3

    正确 .

    在编译时,该列不存在 . 也就是说,SQL Server查看整组命令并解析/编译它 . 代码中的ALTER TABLE的效果对以后的命令不可见 .

    您必须分别对UPDATE执行ALTER TABLE

    注意:对于SQL Server 2005,您将拥有varbinary(max),它更灵活,并且消除了一些复杂性

  • 2

    您的脚本中有几个问题:

    • TempDB 不是 tempdb 的正确名称 . 您的代码将在安装了区分大小写的排序规则的服务器上中断 . 始终对所有数据库名称使用正确的大小写 . 如果在区分大小写的部署下运行,则代码可能会在结果列名称上类似地破坏,如 COLUMN_A .

    • 并发下逻辑错误:会话A将看到会话B的#temp表并执行不正确的操作 .

    • 一个简单的测试表明列是可见的:

    .

    EXEC ('SELECT * INTO #RESULTS_TABLE from 
         (select *, newid() as COLUMN_A from master..spt_values) A;
    ALTER TABLE #RESULTS_TABLE
    ADD IMAGE_DATA varbinary(max);
    IF EXISTS(SELECT * FROM TempDB.INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 
    ''COLUMN_A'' and TABLE_NAME LIKE ''#RESULTS_TABLE%'')
    BEGIN
        update #RESULTS_TABLE 
           set IMAGE_DATA = 0xBAADF00D;
    END
    SELECT * FROM #RESULTS_TABLE')
    

    此测试显示该列已更新,因此检查EXISTS成功 . 显而易见的结论是,在您的情况下,#RESULTS_TABLE和#IMAGE_TABLE之间的 OBJ_ID 连接找不到任何匹配,这是一个完全取决于表内容的问题 .

    编辑

    你可以使 COLUMN_A 成为动态的,它在测试时仍能正常工作:

    declare @cn sysname = case 
          when RAND() * 100 >= 50 then 'COLUMN_A' 
          else 'COLUMN_B' end;
    
    EXEC (N'SELECT * INTO #RESULTS_TABLE from (
         select *, newid() as ' + @cn + N'  from master..spt_values) A;
    ...
    
  • 3

    您可以使用..检查临时表中是否存在列 .

    IF EXISTS (SELECT * FROM TempDB.INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'Column' AND TABLE_NAME LIKE '#TempTable%')
        PRINT 'Column exists'
    ELSE
        PRINT 'Column doesn''t exists'
    

相关问题