я получаю ошибку
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
Ошибка довольно ясна. Чего вы пытаетесь добиться здесь?
@Сергей, извините за сумбурность. Я пытаюсь использовать эти коды для запроса нескольких таблиц, а затем называть объединенные результаты как #RCMTxn.
@cheunghm4532, какая у тебя версия SQL Server?
@Жоров SQL Server 2016
@HoneyBadger, я пытаюсь использовать эти коды для запроса нескольких таблиц (с суффиксом после «EY_RCMTxn_20») с сервера, а затем именовать объединенные результаты как #RCMTxn. Я могу запросить несколько таблиц, но не могу назвать их #RCMTxn.
Если ваш странный SQL работает иначе, не могли бы вы просто сделать отдельный select @sql as XXX INTO #RCMTxn
перед выполнением?
Что именно вы ожидаете от таблицы #RCMTxn? Набор результатов, сгенерированный вашим динамическим SQL?
@JamesZ, я пытался, но потом получил указанную выше ошибку, как только добавил строку «INTO #RCMTxn».
Не в том же операторе, как я уже сказал, выбор отдельный перед выполнением.
@SMor, у меня на сервере около 50 таблиц, все с именами вроде «EY_RCMTxn_202203», «EY_RCMTxn_202204» и т. д. С помощью приведенных выше кодов я смог объединить их все в одну таблицу. Я хочу сохранить эту таблицу с оператором select into, но столкнулся с ошибкой. По сути, когда я добавляю строку «INTO #RCMTxn» перед «FROM», я получаю сообщение об ошибке.
Можете ли вы разделить свою работу на несколько шагов? Как это:
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.
Похоже, вы хотели INTO
внутри динамического SQL.
Также:
nvarchar(max)
для динамического SQLSET @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.
ОК также добавил один для более старых версий
Спасибо! Он работает без ошибок со скриптом старой версии. Впрочем, как назвать стол. Я пытаюсь "SELECT * FROM #RCMTxn", но он говорит: "Недопустимое имя объекта "#RCMTxn"".
Это потому, что вы выбираете за пределами динамический SQL. Чтобы это сработало, вам нужно сначала сделать CREATE TABLE
снаружи, а потом DROP
. Затем удалите INTO
. Это одна из причин, по которой я посоветовал вообще не заморачиваться с временными таблицами. Просто сделайте SELECT ... FROM
внутри динамического SQL, и он даст вам данные
как было предложено, я создал временную таблицу снаружи (см. обновленный сценарий выше), но мне не удается вставить данные во временную таблицу, поскольку она возвращает нулевую строку при запуске «SELECT * FROM #RCMTxn». По той причине, по которой я настаиваю на использовании временных таблиц: мне нужно присоединить много других таблиц к #RCMTxn для вычислений. В очередной раз благодарим за помощь!
Посмотреть последнее редактирование
Ты мой герой!
не могли бы вы уточнить, чего вы хотите достичь с помощью этого странного динамического SQL?