有诸如可移植SQL之类的东西吗?

| 以我的经验,即使有SQL标准,也很难编写能够在大量RDBMS上运行且未经修改的SQL。 因此,我想知道是否有已知的SQL子集(包括DDL,架构等)可在所有主要的RDBMS上工作,包括PostgreSQL,MySQL,SQL Server以及最后但并非最不重要的Oracle。编写可移植SQL时应避免什么样的陷阱? 顺便说一句,是否有一个项目的目标是将有效的SQL子集转换为所有这些供应商使用的特定方言?我知道Hibernate和其他ORM系统必须执行此操作,但是我不希望ORM,而是要编写直接数据库SQL。 谢谢!     
已邀请:
问题在于某些DBMS甚至忽略了最简单的标准(例如,引用引号或字符串连接)。 因此,以下(100%ANSI SQL)不会在每个DBMS上运行:
UPDATE some_table
    SET some_column = some_column || \'_more_data\';
而且我什至没有考虑更高级的SQL标准,例如递归公用表表达式(即使那些支持它的表也不总是遵从)或窗口函数(有些只实现一个非常狭窄的子集,有些不支持所有选项) 。 关于DDL,数据类型存在问题。
DATE
与everywhere2 not并不一样。并非每个DBMS都具有
BOOLEAN
类型或
TIME
类型。 当涉及到约束或领域时,您会获得更多差异。 简而言之,除非您真的需要独立于DBMS,否则请不要理会它。 说了这么多:如果确实要在专有语法和标准语法之间进行选择,请选择标准语法(
OUTER JOIN
vs
(+)
*=
decode
vs
CASE
nvl
vs..11ѭ,依此类推)。     
在每个RDBMS中,所有列出的符合ANSI标准的东西都应该相同,因为这是真正的标准。但是,仅坚持使用ANSI(即便携式)工具,就会失去优化的,特定于供应商的功能。另外,仅仅因为PostgreSQL实现了ANSI函数,并不意味着它可以在任何其他RDBMS中使用(但是,如果可用,那么它应该可以工作)。 就个人而言,我认为真正可移植的SQL代码或将规范化为最低公分集的项目没有价值,因为每个特定的RDBMS的优化方式都不同。没有通用的应用程序语言。如果您使用的是C#,那么您就不想使用只能在PHP或JAVA中找到的东西。因此,只需拥抱您所在的平台即可:)。 编辑:如果您正在编写一个可以连接到多个不同RDBMS的应用程序,则可能需要为每个特定平台找到合适的SQL,就像每个ORM的作者一样。     
简单查询几乎总是可移植的。不幸的是,您提供的SQL供应商列表在其标准遵从性方面差异很大。在符合ANSI SQL标准方面,MS SQL Server在您列出的列表中排在首位,而在遵守标准方面,MySQL和Oracle都非常糟糕。当然,这并不是说它们不是RDBMS引擎不好,或者您不能用它们编写功能强大的查询,但是它们对标准的遵循并不一定就是众所周知的。 请注意,您在该列表中省略了一些大型RDBMS播放器,即Sybase和IBM的DB2。就其价值而言,这两个通常比其他两个更符合标准。     
我可以在一种产品上编写SQL代码并期望它无需修改就可以在另一种产品上工作的理想是无法实现的梦想。 我更认为“可移植性”是一种衡量将代码转移到另一个SQL产品或同一个SQL产品的更高版本的难易程度的衡量标准,并指出已建立的SQL产品倾向于向SQL标准迈进。 (例如,SQL-92的
UPDATE
需要标量子查询,因此处理很长,SQL Server早期提供专有的
JOIN..FROM
语法,然后为SQL Server 2008提供了支持和扩展标准SQLѭ14的Standard14ѭ语法)。 根据经验,请在您的SQL产品支持的地方使用标准SQL代码(例如
CURRENT_TIMESTAMP
而不是SQL Server的ѭ17prefer),否则请选择易于映射到标准SQL代码的专有代码(例如SQL Server的
SUBSTRING()
轻松映射)到标准SQL的“ 18”(使用宏)。请注意,SQL标准以外的某些功能对于SQL产品来说是通用的(例如,大多数/全部将具有
MOD()
函数或运算符)。     
我使用Alpha五构建Web应用程序,该Alpha五具有称为“便携式SQL”的功能。大约有200个“可移植性功能”。如果我使用可移植性功能,它将自动转换为本机SQL以适合我碰巧使用的任何引擎。 因此,如果我编写\“ SELECT now()FROM clients \”,而now()是可移植函数,则该语法将根据我碰巧使用的语言自动转换为母语。它们支持22种不同的SQL引擎。 来自客户端的DB2-SELECT当前时间戳AS Expr1 MYSQL-SELECT Now()AS Expr1来自客户端 来自客户端的MSSQL-SELECT CURRENT_TIMESTAMP AS Expr1 SYBASE-SELECT getdate()AS Expr1来自客户端 ODBC-SELECT {fn Now()} AS Expr1来自客户端     

要回复问题请先登录注册