Сообщение об ошибке SQL: оператор SELECT INTO не может содержать оператор SELECT, который присваивает значения переменной

я получаю ошибку

A SELECT INTO statement cannot contain a SELECT statement that assigns values to a variable

когда я запускаю следующие строки кода на Microsoft SQL Server 2016. Я пытаюсь использовать эти коды для запроса нескольких таблиц (с суффиксом после «EY_RCMTxn_20») с сервера, а затем называю консолидированные результаты как #RCMTxn. Я могу запросить несколько таблиц, но не могу назвать их #RCMTxn.

Как я могу решить эту ошибку?

DROP TABLE IF EXISTS #RCMTxn

DECLARE @sql VARCHAR(MAX)
SET @sql = ''
SELECT @sql = @sql +'
    UNION ALL
    SELECT * FROM ['+name+']'
INTO #RCMTxn
FROM sys.tables
WHERE name LIKE '%EY_RCMTxn_20%'
SET @sql = STUFF(@sql,1,15,'')
EXEC(@sql)

Я использовал приведенный ниже сценарий, предложенный @Charlieface, для создания локальной временной таблицы с именем #RCMTxn снаружи и использования ее в динамическом SQL. Однако я не могу вставить данные во временную таблицу. «Затронуто 752277 строк», когда я запускаю скрипт, но он возвращает нулевую строку, когда я запускаю «SELECT * FROM #RCMTxn».

DROP TABLE IF EXISTS #RCMTxn;
CREATE TABLE #RCMTxn(
    MemberAccountNo VARCHAR(8),
    CardHolderNo VARCHAR(2),
    ActivityDate Date,
    Clubhouse NVARCHAR(255),
    Complex NVARCHAR(255)
)

DECLARE @sep nvarchar(100) = '
UNION ALL
';

DECLARE @sql nvarchar(max) = '
SELECT *
INTO #RCMTxn
FROM (
' +
STUFF((
    SELECT @sep + 'SELECT * FROM ' + QUOTENAME(name) + '
'
    FROM sys.tables
    WHERE name LIKE '%EY_RCMTxn_20%'
    FOR XML PATH(''), TYPE
  ).value('text()[1]','nvarchar(max)'), 1, LEN(@sep), '')
+ '
) t;
';

EXEC sp_executesql @sql;

SELECT * FROM #RCMTxn

не могли бы вы уточнить, чего вы хотите достичь с помощью этого странного динамического SQL?

Sergey 16.05.2022 12:47

Ошибка довольно ясна. Чего вы пытаетесь добиться здесь?

HoneyBadger 16.05.2022 12:48

@Сергей, извините за сумбурность. Я пытаюсь использовать эти коды для запроса нескольких таблиц, а затем называть объединенные результаты как #RCMTxn.

cheunghm4532 16.05.2022 13:02

@cheunghm4532, какая у тебя версия SQL Server?

Zhorov 16.05.2022 13:04

@Жоров SQL Server 2016

cheunghm4532 16.05.2022 13:05

@HoneyBadger, я пытаюсь использовать эти коды для запроса нескольких таблиц (с суффиксом после «EY_RCMTxn_20») с сервера, а затем именовать объединенные результаты как #RCMTxn. Я могу запросить несколько таблиц, но не могу назвать их #RCMTxn.

cheunghm4532 16.05.2022 13:11

Если ваш странный SQL работает иначе, не могли бы вы просто сделать отдельный select @sql as XXX INTO #RCMTxn перед выполнением?

James Z 16.05.2022 13:52

Что именно вы ожидаете от таблицы #RCMTxn? Набор результатов, сгенерированный вашим динамическим SQL?

SMor 16.05.2022 14:03

@JamesZ, я пытался, но потом получил указанную выше ошибку, как только добавил строку «INTO #RCMTxn».

cheunghm4532 16.05.2022 14:03

Не в том же операторе, как я уже сказал, выбор отдельный перед выполнением.

James Z 16.05.2022 14:05

@SMor, у меня на сервере около 50 таблиц, все с именами вроде «EY_RCMTxn_202203», «EY_RCMTxn_202204» и т. д. С помощью приведенных выше кодов я смог объединить их все в одну таблицу. Я хочу сохранить эту таблицу с оператором select into, но столкнулся с ошибкой. По сути, когда я добавляю строку «INTO #RCMTxn» перед «FROM», я получаю сообщение об ошибке.

cheunghm4532 16.05.2022 14:08
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
11
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Можете ли вы разделить свою работу на несколько шагов? Как это:

DROP TABLE IF EXISTS #RCMTxn

DECLARE @sql VARCHAR(MAX);

SET @sql = ''
SELECT @sql = @sql +'
    UNION ALL
    SELECT * FROM ['+name+']'
FROM sys.tables
WHERE name LIKE '%EY_RCMTxn_20%';

SET @sql = STUFF(@sql,1,15,'')

SELECT @sql as sql
INTO #RCMTxn;

EXEC(@sql);

Спасибо за ответ. Однако после запуска вышеуказанных строк кода. Я не могу запросить #RCMTxn с помощью инструкции SELECT * FROM.

cheunghm4532 16.05.2022 14:45
Ответ принят как подходящий

Похоже, вы хотели INTO внутри динамического SQL.

Также:

  • Вам нужно правильно экранировать имена таблиц
  • Используйте nvarchar(max) для динамического SQL
  • Не используйте SET @var += для агрегирования. Используйте STRING_AGG или FOR XML для объединения.
DROP TABLE IF EXISTS #RCMTxn;

DECLARE @sql nvarchar(max) = '
SELECT *
INTO #RCMTxn
FROM (
' +
(
    SELECT STRING_AGG(
'SELECT * FROM ' + QUOTENAME(name), '
UNION ALL
'      )
    FROM sys.tables
    WHERE name LIKE '%EY_RCMTxn_20%'
) + '
) t;
';

EXEC sp_executesql @sql;

Для более старых версий SQL Server вы можете использовать это:

DROP TABLE IF EXISTS #RCMTxn;

DECLARE @sep nvarchar(100) = '
UNION ALL
';

DECLARE @sql nvarchar(max) = '
SELECT *
INTO #RCMTxn
FROM (
' +
STUFF((
    SELECT @sep + 'SELECT * FROM ' + QUOTENAME(name) + '
'
    FROM sys.tables
    WHERE name LIKE '%EY_RCMTxn_20%'
    FOR XML PATH(''), TYPE
  ).value('text()[1]','nvarchar(max)'), 1, LEN(@sep), '')
+ '
) t;
';

EXEC sp_executesql @sql;

Кроме того, вы можете создать таблицу снаружи и сделать обычный INSERT

DROP TABLE IF EXISTS #RCMTxn;

CREATE TABLE #RMCTxn (Column1 ...);

DECLARE @sep nvarchar(100) = '
UNION ALL
';

DECLARE @sql nvarchar(max) = '
INSERT #RMCTxn (Column1 ...)
' +
STUFF((
    SELECT @sep + 'SELECT * FROM ' + QUOTENAME(name) + '
'
    FROM sys.tables
    WHERE name LIKE '%EY_RCMTxn_20%'
    FOR XML PATH(''), TYPE
  ).value('text()[1]','nvarchar(max)'), 1, LEN(@sep), '')
+ '
;
';

EXEC sp_executesql @sql;

Обратите внимание: что бы вы ни делали с временными таблицами, вероятно, можно было бы обойтись и без них.

Спасибо за решение. Я получил ниже сообщение об ошибке при запуске вашего скрипта: «STRING_AGG» не является распознанным именем встроенной функции». и "Необходимо объявить скалярную переменную "@sql"." Я использую версию SQL Server 2016.

cheunghm4532 16.05.2022 17:56

ОК также добавил один для более старых версий

Charlieface 16.05.2022 18:23

Спасибо! Он работает без ошибок со скриптом старой версии. Впрочем, как назвать стол. Я пытаюсь "SELECT * FROM #RCMTxn", но он говорит: "Недопустимое имя объекта "#RCMTxn"".

cheunghm4532 16.05.2022 18:30

Это потому, что вы выбираете за пределами динамический SQL. Чтобы это сработало, вам нужно сначала сделать CREATE TABLE снаружи, а потом DROP. Затем удалите INTO. Это одна из причин, по которой я посоветовал вообще не заморачиваться с временными таблицами. Просто сделайте SELECT ... FROM внутри динамического SQL, и он даст вам данные

Charlieface 16.05.2022 18:47

как было предложено, я создал временную таблицу снаружи (см. обновленный сценарий выше), но мне не удается вставить данные во временную таблицу, поскольку она возвращает нулевую строку при запуске «SELECT * FROM #RCMTxn». По той причине, по которой я настаиваю на использовании временных таблиц: мне нужно присоединить много других таблиц к #RCMTxn для вычислений. В очередной раз благодарим за помощь!

cheunghm4532 17.05.2022 04:34

Посмотреть последнее редактирование

Charlieface 17.05.2022 10:17

Ты мой герой!

cheunghm4532 17.05.2022 10:32

Другие вопросы по теме