运行动态SQL报错:关键字'BY'附近有语法错误(Msg 156)
问题排查与解决
错误原因
报错Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'BY'的核心原因是动态SQL拼接时,表名与GROUP BY关键字之间缺少空格。
比如当@TableName为Total_20240101时,原代码拼接后会生成无效SQL:
SELECT count(distinct(email)) email, Profile,Subscriber,origin,country , '20240101' Date FROM Total_20240101GROUP BY Profile,Subscriber,origin,country
这里Total_20240101GROUP被识别为错误的标识符,直接触发语法报错。
修改后的完整脚本
只需在GROUP BY前添加空格即可修复,同时额外优化了关键字冲突问题:
DROP TABLE IF EXISTS TABLE_NEW_XY CREATE TABLE TABLE_NEW_XY (email VARCHAR(MAX),Profile VARCHAR(MAX),Subscriber VARCHAR(MAX),origin VARCHAR(MAX),country VARCHAR(MAX),[Date] VARCHAR(MAX)) -- 用方括号包裹关键字Date select * from TABLE_NEW_XY DECLARE @Sql NVARCHAR(MAX) = '' ,@TableName VARCHAR(MAX) ,@Id INT DECLARE Table_Cursor CURSOR FOR SELECT ROW_NUMBER() OVER (ORDER BY TABLE_NAME ASC) Id ,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME LIKE 'Total_%' OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @Id,@TableName WHILE @@FETCH_STATUS = 0 BEGIN IF(@Id = 1) BEGIN -- 在GROUP BY前添加空格 SET @Sql = @Sql + 'SELECT count(distinct(email)) email, Profile,Subscriber,origin,country , ''' + RIGHT(@TableName,7) + ''' [Date] FROM '+@TableName+ ' GROUP BY Profile,Subscriber,origin,country' SELECT @SQL END ELSE BEGIN -- 同样添加空格 SET @Sql = @Sql + ' UNION ALL SELECT count(distinct(email)) email, Profile,Subscriber,origin,country,''' + RIGHT(@TableName,7) + ''' [Date] FROM '+@TableName + ' GROUP BY Profile,Subscriber,origin,country' END FETCH NEXT FROM Table_Cursor INTO @Id,@TableName END CLOSE Table_Cursor DEALLOCATE Table_Cursor INSERT INTO TABLE_NEW_XY EXEC (@Sql)
额外优化提示
Date是SQL Server保留关键字,用[Date]包裹可避免潜在语法冲突。- 若字段长度有明确限制,建议替换
VARCHAR(MAX)为对应长度(如VARCHAR(255)),提升存储与查询性能。 - 执行
EXEC (@Sql)前可通过PRINT @Sql打印生成的SQL,快速排查拼接类错误。
内容的提问来源于stack exchange,提问作者nikki
相关产品推荐
相关产品推荐

