如何在大多数RDBMS中检查非转义有效性的标识符?

时间:2011-09-26 18:25:08

标签: sql database database-design identifier

我希望我的应用程序可以在多个数据库上运行。虽然我现在不打算明确支持它们,但我希望能够定义我的模式,以便我不使用保留标识符。原因?标识符分隔符不是数据库之间的标准。例如,MySQL使用反引号(`)来引用标识符,而MSSQL使用括号([])。

但是,我不确定哪些名称的子集是“安全的”。有没有简单的方法来检查这个?

3 个答案:

答案 0 :(得分:3)

主要答案

一个简单的方法?我不这么认为。所以,没有。

一种方法

唯一的方法是查找每个支持的RDBMS的文档。

原因

您总是可以查找ANSI SQL以获取保留字,但最后,每个RDBMS都有其特殊性。

解决方法

让我们从另一个角度来看待这个问题:您可以让部分代码相应地将列转义为RDBMS,而不是让SQL查询避免使用保留名称。

面临的其他问题

列命名不是您唯一的问题。哎呀,这甚至不是你的主要问题!

如果您熟悉MySQL中的GROUP_CONCAT,那么您就知道我的意思了。它在SQL Server中的替代方法是使用XML PATH。 Firebird具有LIST内置聚合函数。最后,最终为每个RDBMS提供不同的查询。我知道因为......

我的经历

我的“去过那里,做过那件事”轶事:我曾在一家公司工作,该公司的主要企业产品应该支持客户现有的RBDMS,可能是Oracle,SQL Server或Informix(不要问)。

最后它的工作原理如下:

  • 这是一个简单的查询吗?尝试将其编写为适用于所有RDBMS;
  • 这是不可能的(意思是:太难/需要花费很多时间)?您的代码中会有IF。没有逃脱(BWAHAHA!),每个RDBMS都有一个查询。
  • 我们测试的所有内容,我们测试了3次:每个RDBMS一次。

结论

让您的应用程序支持多个RDBMS是一个很棒的功能和非常有说服力的销售参数。但是,维护起来并不容易。它需要工作,真的。

您可能认为现在您永远不会使用RDBMS特定查询。但随后出现了一个奇怪的查询很容易被SQL Server和Oracle解决的那一天,但每个人都有自己的方式。但是你尝试使用ANSI SQL编写相同的查询(当然,为什么不呢?)这将花费你几个小时,可能会让你有点疯狂。再次,“去过那里,做到了”。但是不要单独说我的话:与人交谈,最重要的是原型!

答案 1 :(得分:2)

  • 坚持使用字母数字(ASCII A-Z,0-9)加上下划线。
  • 不要以下划线开头(并且必须以字母开头)。
  • 不要求使用分隔标识符 - 假设不区分大小写。
  • 您可能需要研究长度限制 - 旧的SQL标准(SQL-86,SQL-89)限制名称为18个字符,但大多数DBMS目前至少允许31个。
  • 避免使用关键字(但关键字列表是巨大的 - 分别针对每个DBMS,以及所有DBMS中所有关键字的联合)。

答案 2 :(得分:1)

总的来说,我认为这不是一个好的策略,但为了回答您关于标识符的具体问题,我希望您需要在每个案例的基础上确定它们,如果您想避免完全逃避。

您还可以考虑在MySQL中使用ANSI_QUOTES模式 - 然后您可以使用双引号引用SQL Server,Oracle和MySQL的所有标识符 - ANSI标准。

例如,SQL Server 2000“常规标识符”不受限制:http://msdn.microsoft.com/en-us/library/aa223962%28v=sql.80%29.aspx

SQL Server 2005的相同文档:http://msdn.microsoft.com/en-us/library/ms175874%28v=sql.90%29.aspx

SQL Server 2005保留字列表:http://msdn.microsoft.com/en-us/library/ms189822%28v=SQL.90%29.aspx

Oracle 10g的等价物:http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements008.htm

MySQL中的保留字:http://dev.mysql.com/doc/refman/5.6/en/reserved-words.html