Я ожидал получить информацию о том, что колонка не добавлена, но вместо этого получаю ошибку. Почему в этом случае не работает try/catch?
DROP TABLE IF EXISTS #Table
SELECT 1 AS FirstColumn INTO #Table
BEGIN TRY
ALTER TABLE #Table
ADD FirstColumn int;
PRINT 'The column was added correctly'
END TRY
BEGIN CATCH
PRINT 'The column was not added, maybe it already exists?'
END CATCH
В общем, если вы обнаружите, что делаете такое динамическое построение таблицы на временной таблице, настоятельно подумайте о том, чтобы переосмыслить свой подход. В этом заключается боль и безумие - T-SQL действительно хочет, чтобы структуры таблиц были статическими, и вам практически нужно перейти на полностью динамический SQL для всего, если вы откажетесь от этого.
SQL, язык, имеет статическую типизацию, но типы — это таблицы и столбцы, а не int
или varchar
. Вот почему таблица и столбцы не могут быть параметрами или почему вы не можете иметь произвольные столбцы в предложении SELECT
. Даже SELECT *
расширяется до реальных столбцов. Каждое определение данных или оператор манипулирования в вашем скрипте будет скомпилировано отдельно и создаст план выполнения. В этом случае ALTER TABLE #Table ADD FirstColumn int;
не может полностью скомпилироваться
@PanagiotisKanavos: хотя я знаю, что вы имеете в виду, когда говорите, что «таблицы [...] не могут быть параметрами», это утверждение по-прежнему бесполезно сбивает с толку, учитывая, что табличные параметры - это вещь, и что T-SQL разрешает идентификаторы для передаваться без кавычек в хранимые процедуры (sp_rename oldtable, newtable
). Я бы не стал усложнять манеры, говоря, что таблицы — это типы; в T-SQL это не совсем так, а в реляционной алгебре точнее говорить об отношениях и наборах кортежей (и технически нет требования, чтобы они исходили из статически определенных таблиц).
Я не уверен, что любое из этих утверждений пытается заявить, @BogdanSahlean. Пожалуйста, попробуйте перефразировать.
если вы завернете свой код изменения в EXEC («изменить таблицу ...»), он должен работать
Если вы хотите динамически добавить столбец и не уверены, существует ли столбец. Это должно работать:
DROP TABLE IF EXISTS #Table
SELECT 1 AS FirstColumn INTO #Table
IF NOT EXISTS(SELECT 1 FROM tempdb.sys.columns
WHERE Name = N'FirstColumn'
AND Object_ID = OBJECT_ID('tempdb..#Table'))
BEGIN
ALTER TABLE #Table
ADD FirstColumn int;
END
TRY... CATCH
не работает с ошибками компиляции, так как никогда не вводится.