3

DBMS 供应商使用 SQL 方言特性来区分他们的产品,同时声称支持 SQL 标准。'纳夫就此说道。

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

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

我也在谈论您将在生产中使用的查询,而不是临时的东西。

编辑 1 月 13 日

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

4

5 回答 5

4

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

人们可以在大多数情况下跨数据库系统使用 ANSI SQL,并期望在数据库上获得合理的结果,而不会出现诸如丢失索引之类的重大调整问题。但是,在任何非平凡的应用程序中,都可能需要一些不容易移植的代码。

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

因此,在一般情况下,依靠应用程序的“可移植”SQL 构造是不可能的。一个更好的策略是在它们可以工作的地方使用通用语句,并在不工作的地方扩展到数据库特定层。

通用查询机制可能是尽可能使用 ANSI SQL;另一种可能的方法是使用 O/R 映射器,它可以为各种数据库平台获取驱动程序。这种类型的机制应该足以满足大多数数据库操作,但需要您执行一些特定于平台的工作,因为它已经失去动力了。

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

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

于 2010-01-08T13:08:57.203 回答
3

Oracle 有一些附加功能,例如模型分层查询,即使不是不可能,也很难转化为纯 SQL

于 2010-01-08T12:43:10.817 回答
1

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

Oracle 对在 SQL 中放置子查询也有更多的限制。SQL Server 几乎在任何地方都允许子查询更加灵活和宽容。

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

当然,总是有 Oracle 臭名昭著的 SELECT (expression) 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]
于 2010-01-08T13:02:38.493 回答
1

即使 SQL:2008 有时可以做某事,语法也不相同。以 REGEXP 匹配语法为例,SQL:2008 使用LIKE_REGEXvs MySQL 的REGEXP.

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

于 2010-01-08T13:13:24.357 回答
1

常见于 SO

要准确回答:

由于数据类型优先,ISNULL 可以很容易地在 SQL Server 上给出不同的结果作为 COALESCE,根据我的回答/评论here

于 2010-01-08T20:28:51.803 回答