何时/为啥要在 SQL 中使用 QUOTENAME?

Posted

技术标签:

【中文标题】何时/为啥要在 SQL 中使用 QUOTENAME?【英文标题】:When/ why would you use QUOTENAME in SQL?何时/为什么要在 SQL 中使用 QUOTENAME? 【发布时间】:2017-03-29 17:56:40 【问题描述】:

我了解QUOTENAME 函数可用于向字符串添加方括号([],默认行为)或其他一些字符包装。它不适用于较长的字符串(超过 128 个字符)。

那么...为什么/何时使用它而不是更传统且更易读的字符串连接?

为什么您不只是在一个术语的开头和结尾连接一个单引号或一个方括号,而是使用这个函数呢?

【问题讨论】:

Quotename 围绕用于转义字符串的机制添加了一层封装。例如。如果在未来版本的 Sql 中,微软可以将默认字符更改为 " 以更接近 Ansi 标准。 连接更糟糕的具体示例***.com/questions/39919037/… @MartinSmith 谢谢马丁,对不起,我在这里研究时没有看到那个。但我发现你的回答非常有用。 【参考方案1】:

它是/被专门设计用于引用列/表/数据库名称 - sysnames。例如:SELECT QUOTENAME('abc[]def') 返回 [abc[]]def],而 SELECT '[' + 'abc[]def' + ']' 返回 [abc[]def],不能用作列/表/数据库名称。

此外,SQL-99 标准是使用单引号字符进行引用,虽然当前版本的 Sql Server 继续使用括号,但将来可能(或可配置为)使用 SQL-99 标准.在这种情况下,所有使用 QUOTENAME 的代码将继续正常运行,而尝试自行转义的代码将失败。

还有更微妙的含义。由于 QUOTENAME 与 sysname 具有完全相同的限制,如果 Microsoft 决定将 sysname 更改为超过 128 个字符(可能是 256 个?可能是 32767 个?),那么假设 QUOTENAME 也能够处理这些增加的大小。使用 QUOTENAME 是一种从可能不受信任的来源获取列名并将其用作系统名的安全(r)方式——无论当前/未来的数据库设置如何,而不必担心输入中的边缘情况(如 ] 或 ' ) 以及它是否会允许字符串从列名中跳出以创建 SQL 注入攻击。我可能不会仅仅依靠此功能来确保安全性,而是将其用于多个保护层之一。

【讨论】:

附带说明,sysname 并不总是 nvarchar(128)。在 Sql Server 6.5 中,它是 varchar(30)。所以过去发生了变化。未来不能再改变的理由很少。【参考方案2】:

QUOTENAME()主要是在需要构建动态sql的时候使用。您应该尽可能避免使用动态 SQL,但在极少数情况下,它可能是解决问题的最佳方法。在构建动态 SQL 时,QUOTENAME() 是确保可能包含不需要的字符(如空格)的表名和列名变量不会导致最终 SQL 语句出现问题的正确方法。

【讨论】:

【参考方案3】:

QuoteName 主要是为类似 SYSNAME 的数据类型而设计的。此 sysname 数据类型是 128 个字符的 unicode,即 NVARCHAR(128)。因此,如果超过 128 个字符,则需要使用传统的连接方式。但我们可以将 QUOTENAME 用于 varchar、nvarchar 和 sysname 数据类型。

declare @test NVARCHAR(1000) = replicate('a',500)
declare @testsysname sysname = replicate('a',500)

select QUOTENAME(@test) -- this returns null
select QUOTENAME(@testsysname) --this displays only for 128 character with brackets

【讨论】:

以上是关于何时/为啥要在 SQL 中使用 QUOTENAME?的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 时何时/为啥要在变量前加上“$”? [复制]

SQL2008关于quotename的用法

SQL QUOTENAME 添加单引号和逗号

为啥要在 SQL 中使用 WHERE 1=0 语句?

SQL Server:为啥要在存储过程名称的末尾添加“;1”?

为啥使用片段,以及何时使用片段而不是活动?