TSQL: WITH cteTABLE вставить в other_table

Возможный дубликат:
Неправильный синтаксис рядом с ключевым словом 'с'предыдущий оператор должен заканчиваться точкой с запятой

Я хочу выбрать иерархические данные и вставить их в таблицу. Поэтому мне нужно использовать оператор WITH в моей вставке.

Это отлично работает:

create table test_table
(
 id int
)   

with t_table 
as
(select 12345 wert)
insert into test_table (id)
select wert from t_table

Но это генерирует ошибку «неправильный синтаксис рядом с ключевым словом WITH»:

CREATE PROCEDURE p_insert_test
AS
BEGIN

with t_table 
as
(select 12345 wert)
insert into test_table (id)
select wert from t_table

END

Я предполагаю, что T-SQL не любит ключевое слово WITH перед ключевым словом INSERT. Как я могу сделать такую ​​вставку в хранимой процедуре?

Спасибо!


person jzzh    schedule 12.12.2011    source источник
comment
Можете ли вы отредактировать свой пост с точным кодом и ошибкой? В вашем первом блоке кода есть ошибка - его нужно либо запустить как два оператора, либо поставить GO между пакетами. Кроме того, я смог выполнить процедуру без ошибок. Хотя @JNK правильно говорит, что WITH должен быть первым элементом в пакете, единственное требование, которое я здесь вижу, — разделить таблицу создания и специальный with-select.   -  person EBarr    schedule 12.12.2011
comment
@EBarr - первое утверждение работает, а второе - нет. Похоже, вы думаете, что первое утверждение не сработало.   -  person JNK    schedule 12.12.2011
comment
Это правильно. Если вы вырезаете и вставляете первый блок, возникает синтаксическая ошибка (сообщение 102, уровень 15, состояние 1, строка 7. Неверный синтаксис рядом с «t_table»). Он должен иметь GO между таблицей создания и WITH или точкой с запятой после таблицы создания.   -  person EBarr    schedule 13.12.2011


Ответы (1)


Объявление CTE должно быть первой командой в пакете.

Просто поставьте точку с запятой перед WITH и все будет в порядке:

;WITH t_Table...

ИЗМЕНИТЬ:

Чтобы пояснить, почему это так, ключевое слово WITH также используется для подсказок запроса, таких как WITH RECOMPILE, WITH (NOLOCK) и т. д. Механизм запросов должен знать назначение ключевого слова WITH и единственный способ обозначить, что он представляет CTE, состоит в том, чтобы гарантировать, что объявления CTE являются началом пакета.

В противном случае у вас может быть что-то неоднозначное, например:

SELECT Field
FROM MyTable
WITH CteName
As
(Select 1)

Без признака конца оператора CteName будет неправильно прочитано как подсказка запроса, примененная к MyTable.

person JNK    schedule 12.12.2011
comment
+1 : Или, в качестве альтернативы, убедитесь, что предыдущая команда завершается символом ;. В большинстве случаев это необязательно, но при использовании CTE требуется «правильно» завершить предыдущую команду. - person MatBailie; 12.12.2011