SQL 错误消息:SELECT INTO 语句不能包含为变量赋值的 SELECT 语句

SQL Error Msg: A SELECT INTO statement cannot contain a SELECT statement that assigns values to a variable

我收到错误

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

当我 运行 Microsoft SQL Server 2016 上的以下代码行时。我正在尝试使用这些代码来查询多个 table(在“EY_RCMTxn_20"),然后将合并结果命名为#RCMTxn。我可以查询多个 tables,但无法将其命名为#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 的本地临时文件table 并在动态SQL 中使用它。但是,我无法将数据插入临时 table。当我 运行 脚本时,“752277 行受影响”,但当我 运行 “SELECT * FROM #RCMTxn”.

时,它 returns 零行
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

你能把你的工作分成更多的步骤吗?像这样:

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);

看起来你想要动态 SQL 中的 INTO

还有:

  • 您需要正确转义 table 名称
  • 对动态使用 nvarchar(max) SQL
  • 不要使用SET @var +=来聚合。使用 STRING_AGGFOR 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服务器,你可以使用这个:

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;

或者,您可以在外部创建 table 并执行正常的 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;

请注意,无论您使用 temp tables 做什么,都可以不用。