У меня есть простая таблица тестов, как это:
CREATE TABLE MyTable (x INT);
В рамках транзакции я пытаюсь добавить столбец, а затем вставить его во вновь созданный столбец:
BEGIN TRANSACTION;
PRINT 'Adding column, ''SupplementalDividends'', to MyTable table.';
ALTER TABLE MyTable
ADD SupplementalDividends DECIMAL(18,6);
PRINT 'Column added successfully....';
PRINT 'Ready to INSERT into MyTable ...';
INSERT INTO MyTable (x, SupplementalDividends)
VALUES (1, 3.2);
PRINT '**** CHANGES COMPLETE -- COMMITTING.';
COMMIT TRANSACTION;
Проблема - сообщение об ошибке, когда я запускаю приведенный выше код:
Invalid column name 'SupplementalDividends'.
Почему это вызывает ошибку? Если я добавлю столбец в другой пакет, вне транзакции, он будет работать. Моя проблема в том, что я хочу добавить столбец в транзакции. Почему ошибка?
sql-server
sql-server-2008-r2
t-sql
Том Бакстер
источник
источник
schema.ObjectName
. Хорошее начало для адаптации хорошей практики :-)Ответы:
Просто хочу уточнить, что это проблема во время выполнения, а не во время компиляции, и не имеет ничего общего с тем, что они находятся в одной транзакции . Например, предположим, у нас есть эта таблица:
Следующий пакет успешно анализирует (время компиляции), но во время выполнения получает ошибку, о которой вы упомянули в вопросе:
В редакторе запросов в Management Studio вы можете легко обойти это, либо:
Ввод пакетное разделитель между ними, например , так:
Если вы запускаете это из-за пределов SQL Server (например, отправляете пакет SQL из кода вашего приложения), вы можете просто отправить две партии отдельно, аналогичным образом, или, если вам абсолютно необходимо отправить его как один пакет, вы можете используйте динамический SQL (как в ответе Джанлуки ), чтобы отложить разрешение имен.
источник
Это обязательный вопрос. Код привязан к метаданным таблицы во время компиляции, и он не привязан поздно. Попробуйте использовать EXEC и динамический SQL, чтобы преодолеть это ограничение:
Другой вариант - использование хранимой процедуры для вставки данных: поздняя привязка применяется к хранимой процедуре, но не к специальным запросам. Опять же, вам придется использовать динамический SQL для создания процедуры, но это может упростить передачу параметров:
Временная хранимая процедура также будет работать:
источник
Мне любопытно, почему вы изменяете таблицу и вставляете значение в этот столбец в той же транзакции.
Почти нет шансов, что вам когда-нибудь понадобится снова изменить таблицу (точно таким же образом), если только она не переворачивается каждый час / день, так зачем делать это в транзакции?
Ваше изменение еще не было совершено, и поэтому оно не найдено, когда вы пытаетесь вставить в него.
Мой совет - разделять задачи DDL и DML (по крайней мере, в отдельных транзакциях).
источник