我们将为我们的客户提供一个工具(除其他外)创建一个新的SQL Server数据库,我希望能够对他们提供的数据库名称进行基本验证。 SQL Server的文档说明了数据库名称中有效的字符。但是,文档显然是不正确的,因为我可以成功创建名称违反记录规则的数据库。
根据SQL Server的CREATE DATABASE文档,数据库名称必须符合标识符规则; identifiers的规则取决于数据库兼容级别。当兼容级别为100(根据SQL Server Management Studio,表示“SQL Server 2008”)时,名称必须以Unicode字母_
,@
或{{1}开头};后跟一个或多个字母,数字,#
,@
,$
或#
。文档明确指出不允许嵌入空格或特殊字符。
这面对现有证据,因为我可以使用SQL Server Management Studio创建一个名为_
的数据库 - 它不仅包含嵌入空格(显式禁止),还包含特殊字符(This & That | "Other"
,|
)在文件名中甚至无效。我检查过,数据库的兼容级别确实是“SQL Server 2008(100)”,即使它的名称在该兼容级别被记录为无效。
哎呀,我甚至可以"
(是的,这是一个单独的空格),这证明第一个字符不必须是一个字母,下划线,符号,或者英镑符号。
所以我想我的问题是,SQL Server数据库名称中哪些字符 有效?是否有任何与SQL Server实际行为一致的文档规则?
答案 0 :(得分:28)
使用标识符时 Transact-SQL语句, 不符合的标识符 这些规则必须由以下划定 双引号或括号。
通过选择不符合这些规则的数据库名称,必须始终用双引号或括号括起来。
如果遵守常规标识符的规则,则可以使用不带引号/括号的数据库名称。
以下说明没问题
CREATE DATABASE [conformingName]
CREATE DATABASE conformingName
CREATE DATABASE [This & That | "Other"]
但不是
CREATE DATABASE This & That | "Other"
编辑:
我同意这不是人们理解链接文档的方式:必须遵守标识符规则是什么意思,如果规则不再适用,一旦标识符被包含在内?关于包含不符合标识符的观点应该是规则的一部分。
答案 1 :(得分:10)
常规标识符和分隔标识符之间存在差异。常规标识符受您提到的限制的约束,而分隔标识符可以包含任何字符(分隔符除外)。
当您在标识符周围使用引号时,它是一个分隔标识符,并且您不受常规标识符规则的限制。
如果没有分隔符,则只能创建标识符遵循常规标识符规则的数据库:
create database db_name
使用分隔符,您几乎可以使用任何东西:
create database "That's a funny name, isn't it?"
create database [)(/%Q)/#&%¤)Q/#)!]
答案 2 :(得分:7)
就我个人而言,我会将它们限制在字母和数字中,而不是其他任何东西(很可能也是_)。没有空格,没有有趣的符号,没有回车等。这是最安全的。
答案 3 :(得分:3)
分隔名称 - 用方括号或双引号括起来(如果QUOTED_IDENTIFIER设置为ON) - 基本上可以包含分隔符本身以外的任何内容。甚至可以使用名称中的分隔符和一些转义逻辑。请注意,它只是必须转义的结束转义字符。在下面的第一个示例中,名称中的打开转义字符的单个实例不需要转义,而关闭转义字符必须进行转义(通过将单个实例替换为两个)。我想这里的逻辑是,解析这些语句的任何代码都在寻找一个结束转义字符,并且对嵌套的开始转义字符不感兴趣。
以下是SQL Server 2012中围绕非分隔(非引用)标识符名称的规则的说明。它是文档Guide to Migrating from MySQL to SQL Server 2012的摘录。
架构对象名称
在SQL Server 2012中,对象名称最长可达128个字符。
非引用标识符名称必须遵循以下规则:
- 第一个字符必须是字母数字,下划线(_),符号(@)或数字符号(#)。
- 后续字符可以包含字母数字字符,下划线,at(@)符号,数字符号或美元符号。
- 标识符不能是Transact-SQL保留字。从MySQL迁移到SQL Server 2012的指南8
- 不允许使用嵌入空格或特殊字符。
以@或数字符号开头的标识符具有特殊含义。 以@开头的标识符是局部变量名。那些开始 带有数字符号的是临时表名。
要在Transact-SQL中引用标识符名称,必须使用square 括号([])。