【问题标题】:Adding a new column to a table getting the column name from another table将新列添加到表中,从另一个表中获取列名
【发布时间】:2021-11-05 07:42:54
【问题描述】:

我正在使用 Microsoft SQL 服务器管理工​​作室。

我想向表 (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 如下所示:

日期 |Adat
2021-09-08 |1

2021-09-08 是每日生成的数据:

**CONVERT(date,GETDATE())**

【问题讨论】:

  • 您为什么要想要一个名称为日期的列?对我来说听起来像是XY Problem
  • 然而,错误告诉你问题所在。 ALTER TABLE altertable1 ADD 2021-06-08 nvarchar(20); 语法无效。
  • EXEC(@sql) 更改为PRINT @sql; 是一种非常强大但未被充分利用的调试技术。

标签: sql-server dynamic-sql alter-table declare


【解决方案1】:

就像 Larnu 在评论中说的那样,也许这对你来说不是主要问题,但如果你想这样做,当你想命名以数字开头的列时添加 [ ]

像这样:

SET @sql = 'ALTER TABLE altertable1 ADD [' + @Data  + '] nvarchar(20)'

当然,按日期或年份命名列并不是最佳做法。

【讨论】:

  • 小心'[' + @Data + ']' 注射安全。
  • @Larnu,按照阿德里安的逻辑,一切都不安全。我建议他更改有关此更改表的所有内容,但这是他问题的答案。
  • 我不反对改变设计,这就是为什么我没有回答,但是,如果你正在注入动态对象名称,你应该使用QUOTENAME;一旦你得到一个带有] 字符的字符串,上面的内容就会崩溃。
  • 这是一种更好的思维方式,而且都是正确的。但是,因为他尝试使用日期/年份,我认为这是这里的问题。一般是的。
  • Larnu 的观点是,即使在您认为不是绝对必要的情况下,您也应该展示最佳实践而不是不安全的实践。除此 OP 之外的读者将从此代码中学习,并假设只需拍手册 [] 就可以了。不是。
【解决方案2】:

您的整体设计的问题在于您似乎每天都在向表格添加一列。表格不是电子表格,您应该将每天的数据存储在 中,而不是单独的列中。如果您的报告需要以这种方式显示,有很多方法可以转换数据,以便您可以在演示时处理它,而不会在数据库中产生无法维护的技术债务。

您当前代码的问题是 2021-06-08 不是有效的列名,因为它以数字开头,而且因为它包含破折号。即使您使用像 YYYYMMDD 这样对语言更友好的形式(请参阅 this article 了解我的意思),它仍然以数字开头。

解决本地问题的最佳方法是不要以这种方式命名列。如果必须,正确的逃脱方法是使用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;

这也展示了您调试语句的能力,而不是试图破译来自您无法检查的字符串的错误消息。

需要考虑的其他几点:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2018-03-06
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多