Как выполнить оператор sql через переменную (динамический sql), которая пытается выполнить вставку в таблицу переменных?

Возможный дубликат:
Как использовать табличную переменную в динамическом операторе sql?

Если я делаю то, что хочу, с ВРЕМЕННОЙ ТАБЛИЦЕЙ, все работает нормально:

DECLARE @CTRFR VARCHAR(MAX)

SET @CTRFR = 'select blah blah blah' -- <-- very long select statement. this returns a 0 or some greater number. Please note! --> I NEED THIS NUMBER.

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo][#CTRFRResult]') AND type IN (N'U') ) 
   DROP TABLE [dbo].[#CTRFRResult]

CREATE TABLE #CTRFRResult
(
  CTRFRResult VARCHAR(MAX)
)

SET @CTRFR = 'insert into #CTRFRResult ' + @CTRFR
EXEC(@CTRFR)

Вышеупомянутое работает нормально.

Проблема в том, что несколько баз данных используют одну и ту же таблицу TEMP. Поэтому мне нужно использовать таблицу VARIABLE (вместо временной таблицы).

То, что у меня есть ниже, не работает, потому что оно говорит, что таблица должна быть объявлена.

DECLARE @CTRFRResult TABLE
(
   CTRFRResult VARCHAR(MAX)
)

SET @CTRFR = 'insert into @CTRFRResult ' + @CTRFR -- I think the issue is here.
EXEC(@CTRFR)

Установка @CTRFR на insert into... не работает, потому что я предполагаю, что имя таблицы выходит за рамки. Как мне имитировать код временной таблицы с помощью таблицы переменных?

Сообщение об ошибке, которое я получаю:

Необходимо объявить табличную переменную "@CTRFRResult"


person RJ.    schedule 18.09.2012    source источник


Ответы (3)


Вы не можете использовать таблицу @ с таким динамическим SQL, вам также придется создать таблицу в динамическом операторе sql.

Но я не думаю, что у вас есть проблемы с использованием # таблиц.

Таблица # будет доступна только для текущего сеанса — у вас могут быть сотни сеансов, каждый из которых создает свою собственную версию без проблем.

Если вы хотите создать временную таблицу, к которой могут получить доступ другие сеансы, вам нужно вместо этого использовать ##.

person Mister Bee    schedule 18.09.2012
comment
проблема в том, что несколько сеансов создают ОДИНАКОВОЕ имя таблицы. Я думаю, что это проблема, с которой я столкнулся. это создает объект X, тогда кто-то еще запускает другую sproc, которая создает объект X, вызовет проблему, нет? - person RJ.; 19.09.2012
comment
@Testifier, локальные временные таблицы (созданные как #TableName) не имеют этой проблемы, поскольку ядро ​​базы данных делает это путем внутреннего добавления числового суффикса к каждому имени локальной временной таблицы. Ознакомьтесь с разделом Локальная временная таблица на этой странице. - person Tim Lehner; 19.09.2012
comment
@TimLehner, как мне узнать имя временной таблицы, имя которой было изменено SQL, когда я собираюсь удалить эти временные таблицы? - person RJ.; 19.09.2012
comment
@Testifier, SQL Server отслеживает это для вас. Просто создайте одну и ту же временную таблицу в двух окнах SQL Server Management Studio. Затем добавьте данные, затем запросите их, а затем удалите. Они все время разные, потому что сделаны в двух разных сессиях. - person Tim Lehner; 19.09.2012
comment
@Testifier: то, что говорит Тим, верно, SQL Server управляет всем этим за вас. Поищите в онлайн-книгах по SQL описание различий между # таблицами и ## таблицами. - person Mister Bee; 19.09.2012

Вы не можете вставить в табличную переменную, подобную этой, поскольку exec работает в своей собственной области.

Из книги Эрланда Соммарскога Проклятие и благословения динамического SQL:

Следующее, на что следует обратить внимание, это то, что динамический SQL не является частью хранимой процедуры, а составляет ее собственную область. Вызов блока динамического SQL подобен вызову безымянной хранимой процедуры, созданной ad-hoc. Это имеет ряд последствий:

В блоке динамического SQL вы не можете получить доступ к локальным переменным (в том числе табличным переменным) или параметрам вызывающей хранимой процедуры. Но вы можете передавать параметры — входящие и исходящие — в блок динамического SQL, если используете sp_executesql.

person Tim Lehner    schedule 18.09.2012

Хотя вы ничего не можете сделать с отправкой табличной переменной в качестве параметра в динамический sql или другую хранимую процедуру, вы все равно можете использовать ее в своем конкретном случае. Вместо

SET @CTRFR = 'insert into @CTRFRResult ' + @CTRFR -- I think the issue is here.
EXEC(@CTRFR)

Вы можете поставить:

insert into @CTRFRResult
  exec sp_executesql @CTRFR
person Nikola Markovinović    schedule 18.09.2012