普通的SQL与方言

时间:2010-01-08 12:38:58

标签: sql tsql generics sql-standards

DBMS供应商使用SQL方言功能来区分他们的产品,同时声称支持SQL标准。 '努夫在这说了。

是否有任何已编码的SQL无法转换为SQL的示例:2008标准SQL?

具体来说,我说的是DML(查询语句),NOT DDL,存储过程语法或任何非纯SQL语句。

我也在谈论你将在制作中使用的查询,而不是ad-hoc的东西。

编辑1月13日

感谢您的所有答案:他们向我传达了一种印象,即创建了许多特定于DBMS的SQL,以便为糟糕的关系设计提供解决方案。这导致我得出结论,您可能不希望移植大多数现有应用程序。

5 个答案:

答案 0 :(得分:3)

Oracle有一些新增内容,例如modelhierarchical查询,如果不是不可能的话,很难翻译成纯SQL

答案 1 :(得分:3)

典型的差异包括微妙的不同语义(例如Oracle在某些情况下处理NULL与其他SQL方言不同),不同的异常处理机制,不同的类型以及用于执行字符串操作,日期操作或分层查询等操作的专有方法。查询提示也往往具有不同平台的语法,不同的优化者可能会对不同类型的结构感到困惑。

大多数人可以在数据库系统中使用ANSI SQL,并希望在数据库上获得合理的结果,而不会出现丢失索引等重大调优问题。但是,在任何非平凡的应用程序中,可能需要一些代码无法轻松完成。

通常,此要求将在应用程序代码库中进行相当本地化 - 少数查询导致问题。报告更有可能引发此类问题,并且执行跨数据库管理器工作的通用报告查询不太可能正常工作。有些应用程序比其他应用程序更容易引起悲伤。

因此,依赖于应用程序的“可移植”SQL构造不太可能在一般情况下起作用。一个更好的策略是使用通用语句,它们将工作并突破到数据库特定的层,但这不起作用。

通用查询机制可能是在可能的情况下使用ANSI SQL;另一种可能的方法是使用O / R映射器,它可以为各种数据库平台提供驱动程序。这种类型的机制应该足以满足大多数数据库操作的需要,但是需要你在没有蒸汽的情况下做一些特定于平台的工作。

您可以将存储过程用作更复杂操作的抽象层,并为每个目标平台编写一组特定于平台的sproc。可以通过ADO.net之类的东西访问sprocs。

在实践中,参数传递和异常处理的细微差别可能会导致此方法出现问题。更好的方法是生成一个包装的模块 具有通用接口的特定于平台的数据库操作。根据您使用的DBMS平台,可以交换不同的“驱动程序”模块。

答案 2 :(得分:1)

Oracle的部分问题在于它仍然基于SQL 1992 ANSI标准。 SQL Server符合SQL 1999标准,因此一些看起来像“扩展”的东西实际上是更新的标准。 (我相信“OVER”条款就是其中之一。)

Oracle在将子查询放入SQL中的限制也要大得多。 SQL Server在允许子查询几乎在任何地方都更加灵活和宽容。

SQL Server有一种合理的方法来选择结果的“顶部”行:“按照SALES_TOTAL从客户订单中选择TOP 1”。在Oracle中,这变为“SELECT * FROM(SELECT CUSTOMERS ORDER BY SALES_TOTAL)WHERE ROW_NUMBER< = 1”。

当然,Oracle总是臭名昭着的SELECT(表达式)FROM DUAL。

编辑添加:

现在我正在工作并且可以访问我的一些示例,这是一个很好的例子。这是由LINQ-to-SQL生成的,但是在排序之后从表中选择行41到50是一个干净的查询。它使用“OVER”子句:

SELECT [t1].[CustomerID], [t1].[CompanyName], [t1].[ContactName], [t1].[ContactTitle], [t1].[Address], [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[Country], [t1].[Phone], [t1].[Fax]
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ContactName]) AS [ROW_NUMBER], [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
        FROM [dbo].[Customers] AS [t0]
        ) AS [t1]
    WHERE [t1].[ROW_NUMBER] BETWEEN 40 + 1 AND 40 + 10
    ORDER BY [t1].[ROW_NUMBER]

答案 3 :(得分:1)

即使SQL:2008有时可以做某事,语法也不一样。以REGEXP匹配语法为例,SQL:2008使用LIKE_REGEX vs MySQL的REGEXP

是的,我同意,这很烦人。

答案 4 :(得分:1)

这里常见于SO

准确回答:

ISNULL可以轻松地在SQL Server上提供与COALESCE不同的结果,因为数据类型优先,根据answer/comments这里