我使用Microsoft SQL server管理工作室
我想在表(altertable1)中添加一个新列,并使用另一个表(stattable1)的单元格(Date)中的数据命名该列。
DECLARE @Data nvarchar(20)
SELECT @Data = Date
FROM stattable1
WHERE Adat=1
DECLARE @sql nvarchar(1000)
SET @sql = 'ALTER TABLE altertable1 ADD ' + @Data + ' nvarchar(20)'
EXEC (@sql)
执行此操作,我得到以下错误,无法找出原因:
'2021'附近语法错误。">
stattable1是这样的:
日期|日期
2012-09-08 |1
20121-09-08为每日生成数据:
**CONVERT(date,GETDATE())**
就像Larnu在评论中说的,也许这对你来说不是一个主要问题,但是如果你想这样做,当你想要命名以数字开头的列时,添加[ ]
。
:
SET @sql = 'ALTER TABLE altertable1 ADD [' + @Data + '] nvarchar(20)'
当然,按日期或年份命名列不是最佳实践。
总体设计的问题是,您似乎每天都要向表中添加一列。表格不是电子表格,您应该将每天的数据存储在行中,而不是单独的列中。如果您的报告需要以这种方式呈现,那么有许多方法可以透视数据,以便您可以在演示时处理数据,而不会在数据库中创建无法维护的技术债务。
当前代码的问题是2021-06-08
不是有效的列名,这既是因为它以数字开头,也是因为它包含破折号。即使您使用更语言友好的形式,如YYYYMMDD
(请参阅本文了解我的意思),它仍然以数字开头。
局部问题的最佳解决方案是不以这种方式命名列。如果你必须,正确的方法来逃避它是使用QUOTENAME()
(而不仅仅是手动拍打[
和]
在任何一边):
DECLARE @Data nvarchar(20), @sql nvarchar(max);
SELECT @Data = Date
FROM dbo.stattable1
WHERE Adat = 1;
SET @sql = N'ALTER TABLE altertable1
ADD ' + QUOTENAME(@Data) + N' nvarchar(20);';
PRINT @sql;
--EXEC sys.sp_executesql @sql;
这也证明了您调试语句的能力,而不是试图破译来自无法检查的字符串的错误消息。
其他需要考虑的问题:
- 如果你声明一个字符串为
nvarchar
,特别是在处理SQL Server元数据时,总是在你定义的任何文字上使用N
前缀。 - 总是引用由两部分组成的用户表名。
- 总是用语句终止符结束语句。
- 一般选择
sys.sp_executesql
而不是EXEC()
。 关于动态SQL的一些建议: - 保护自己免受SQL注入-第1部分 保护您自己免受SQL注入-第2部分