SQL Server数据库名称中有哪些字符有效?

Joe*_*ite 49 t-sql sql-server identifier

我们将为我们的客户提供一个工具(除其他外)创建一个新的SQL Server数据库,我希望能够对他们提供的数据库名称进行基本验证.SQL Server的文档说明了数据库名称中有效的字符.但是,文档显然是不正确的,因为我可以成功创建名称违反记录规则的数据库.

根据SQL Server的CREATE DATABASE文档,数据库名称必须符合标识符规则; 标识符的规则取决于数据库兼容级别.当兼容水平为100(其中,根据SQL Server Management Studio中,意思是"的SQL Server 2008"),该名称必须以一个Unicode字母,_,@,或#; 后跟一个或多个字母,数字,@,$,#,或_.文档明确指出不允许嵌入空格或特殊字符.

这是因为我可以使用SQL Server Management Studio创建一个名称为的数据库This & That | "Other"- 它不仅包含嵌入空格(显式禁止),而且包含不均匀的特殊字符(|,")在文件名中有效.我检查过,数据库的兼容级别确实是"SQL Server 2008(100)",即使它的名称在该兼容级别被记录为无效.

哎呀,我甚至可以做的CREATE DATABASE " "(是的,这是一个空格),这证明了第一个字符并没有必须是字母,下划线,@符号,或井号.

所以我想我的问题是,哪些字符在SQL Server数据库名称有效?是否有任何与SQL Server实际行为一致的文档规则?

mar*_*pet 28

标识符规则的末状态:

在Transact-SQL语句中使用标识符时,不符合这些规则的标识符必须用双引号或括号分隔.

通过选择不符合这些规则的数据库名称,您必须始终用双引号或括号将其括起来.

如果遵守常规标识符的规则,则可以使用不带引号/括号的数据库名称.

以下说明没问题

CREATE DATABASE [conformingName]
CREATE DATABASE conformingName
CREATE DATABASE [This & That | "Other"]
Run Code Online (Sandbox Code Playgroud)

但不是

CREATE DATABASE This & That | "Other"
Run Code Online (Sandbox Code Playgroud)

编辑:

我同意这不是人们如何理解链接文档:必须遵守标识符规则意味着如果规则不再适用于标识符后立即应用的那些规则?关于包含不符合标识符的观点应该是规则的一部分.

  • 试试吧!是的,任何事情都有.我创建了一个名为~` ^%$£的数据库名称 (5认同)
  • 好的,我明白了.但是这些文档似乎并没有说明这些引用内部有效和无效的内容.这是否意味着*什么*去了?非法的Unicode字符?`\ 0`?还是有规则吗? (4认同)

Guf*_*ffa 10

常规标识符和分隔标识符之间存在差异.常规标识符受您提到的限制的约束,而分隔标识符可以包含任何字符(分隔符除外).

当您在标识符周围使用引号时,它是一个分隔标识符,并且您不受常规标识符规则的限制.

如果没有分隔符,则只能创建具有遵循常规标识符规则的标识符的数据库:

create database db_name
Run Code Online (Sandbox Code Playgroud)

使用分隔符,您可以使用几乎任何东西:

create database "That's a funny name, isn't it?"

create database [)(/%Q)/#&%¤)Q/#)!]
Run Code Online (Sandbox Code Playgroud)

  • 解释*虽然定界标识符可以包含除**分隔符*之外的任何字符**.我可以简单地输入两次字符来逃避它,例如:**create database""""**或者甚至**create database []]]** (2认同)

HLG*_*GEM 7

就个人而言,我会将它们限制在字母和数字中,而不是其他任何东西(很可能也是_).没有空格,没有有趣的符号,没有回车等.这是最安全的.

  • @Pacerier,你永远不知道什么系统或代码可以在某个时候处理你的whacky数据库名称和爆炸,因为你使用的字符,它的开发人员太短视,即使SQL Server可以使用它们. (8认同)
  • 根本没有意义.究竟怎么更安全? (4认同)
  • 对于可能不会考虑特殊字符的数据库运行脚本而言,它更安全. (3认同)
  • 实际上,这根本不安全。当你在编程时,你必须假设所有的可能性。如果您认为标识符总是安全的,那么您就容易受到攻击,例如代码注入。 (2认同)
  • @HLGEM尝试将数据库命名为“ d;删除数据库主数据库;” (2认同)

Sco*_*nro 5

分隔名称 - 用方括号或双引号括起来(如果QUOTED_IDENTIFIER设置为 ON) - 基本上可以包含除分隔符本身以外的任何内容。甚至可以在名称中使用带有一些转义逻辑的分隔符。但请注意,必须转义的只是结束转义字符。在下面的第一个示例中,名称中开始转义字符的单个实例不需要转义,而结束转义字符则必须转义(通过将单个实例替换为两个)。我想这里的逻辑是,解析这些语句的任何代码都在寻找结束转义字符,并且对嵌套的开始转义字符不感兴趣。

  • [测试[测试] -> 测试[测试]
  • [测试]]测试] -> 测试]测试

以下是 SQL Server 2012 中围绕非分隔(非引号)标识符名称的规则的说明。它是文档从 MySQL 迁移到 SQL Server 2012 的指南的摘录。

架构对象名称

在 SQL Server 2012 中,对象名称最长可达 128 个字符。

不带引号的标识符名称必须遵循以下规则:

  • 第一个字符必须是字母数字、下划线 (_)、at 符号 (@) 或数字符号 (#)。
  • 后续字符可以包括字母数字字符、下划线、at (@) 符号、数字符号或美元符号。
  • 标识符不能是 Transact-SQL 保留字。从 MySQL 迁移到 SQL Server 2012 的指南 8
  • 不允许嵌入空格或特殊字符。

以@ 或数字符号开头的标识符具有特殊含义。以@ 开头的标识符是局部变量名。以数字符号开头的那些是临时表名。

要在 Transact-SQL 中引用标识符名称,必须使用方括号 ([])。