Проверка наличия столбца во временной таблице всегда возвращает false в SQL Server - PullRequest
4 голосов
/ 13 июня 2011

У меня есть следующий оператор Execution, который создает таблицу (используя данные из другой процедуры), вставляет значения во временную таблицу, добавляет столбец изображения (поскольку они не могут быть включены в группу), а затем обновляет его на основе критерии из другой временной таблицы (результирующие поля таблицы используются в отчете 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 голосов
/ 13 июня 2011

У вас есть несколько проблем в вашем скрипте:

  • TempDB не является правильным именем tempdb.Ваш код будет работать на сервере, установленном с учетом сортировки с учетом регистра.Всегда используйте правильный регистр для всех имен баз данных.Ваш код, вероятно, будет ломаться аналогичным образом в именах столбцов результата, например COLUMN_A, если он запускается в чувствительном к регистру развертывании.
  • Логика неверна в параллельном режиме: сеанс A увидит таблицу #temp сеанса B и выполнит неправильные действия.
  • Простой тест показывает, что столбцы видимы :

.

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 прошла успешно.Очевидный вывод состоит в том, что в вашем случае объединение OBJ_ID между #RESULTS_TABLE и #IMAGE_TABLE не находит соответствия, что является проблемой, которая полностью зависит от содержимого ваших таблиц.1025 *

Вы можете сделать 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 голосов
/ 18 ноября 2014

Проверить наличие столбца во временной таблице можно с помощью ..

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'
2 голосов
/ 13 июня 2011

Правильно.

На момент компиляции столбец не существует.Таким образом, SQL Server просматривает весь набор команд и анализирует / компилирует его.Последствия команды ALTER TABLE в коде не будут видны последующим командам.

Вы должны выполнить ALTER TABLE отдельно от ОБНОВЛЕНИЯ

Примечание.иметь varbinary (max), который намного более гибок и устраняет некоторую сложность

...