据我所知,QUOTENAME函数可用于添加方括号(默认行为)或其他一些字符包装器。 QUOTENAME不适用于较长的字符串(超过128个字符)。所以我的问题是,为什么/何时使用它而不是更传统和更容易阅读的字符串连接。为什么不在一个术语的开头和结尾连接单个引号或方括号而是使用此函数?
答案 0 :(得分:17)
它是/专门用于引用列/表/数据库名称 - 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)方法,可以从可能不受信任的来源获取列名并将其用作sysname - 无论当前/未来的数据库设置如何,而不必担心边缘情况(如]或'输入内部)以及是否允许字符串突破列名以创建SQL注入攻击。我可能不会仅仅依赖于此功能的安全性,而是可以用于多层保护之一。
答案 1 :(得分:3)
主要在需要构建动态sql时使用QUOTENAME()
。动态SQL是您应该尽可能避免的,但在极少数情况下,它可能是解决问题的最佳方法。构建动态SQL时,QUOTENAME()
是确保包含空格等不需要的字符的表名和列名变量不会导致最终SQL语句出现问题的正确方法。
答案 2 :(得分:1)
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