3

DBMS ベンダーは、SQL ダイアレクト機能を使用して製品を差別化すると同時に、SQL 標準をサポートしていると主張しています。これについてナフは言った。

SQL:2008 標準 SQL に変換できないコード化された SQL の例はありますか?

具体的には、DML (クエリ ステートメント)、NOT DDL、ストアド プロシージャ構文、または純粋な SQL ステートメントではないものについて話しています。

また、アドホックなものではなく、本番環境で使用するクエリについても話しています。

1月13日編集

すべての回答に感謝します。お粗末なリレーショナル デザインの回避策を可能にするために、多くの DBMS 固有の SQL が作成されているという印象を受けました。これにより、ほとんどの既存のアプリケーションを移植したくないという結論に至ります。

4

5 に答える 5

4

典型的な違いには、微妙に異なるセマンティクス (たとえば、Oracle は場合によっては他の SQL ダイアレクトとは異なる方法で NULL を処理する)、異なる例外処理メカニズム、異なる型、および文字列操作、日付操作、階層クエリなどを実行するための独自のメソッドが含まれます。クエリ ヒントは、プラットフォームによって異なる構文を持つ傾向があり、さまざまなオプティマイザーがさまざまな種類の構造で混乱する可能性があります。

ANSI SQL は、ほとんどのデータベース システムで使用でき、インデックスの欠落などの重大なチューニングの問題がなくても、データベースで妥当な結果が得られると期待できます。ただし、重要なアプリケーションでは、簡単に移植できないコードが必要になる可能性があります。

通常、この要件はアプリケーション コード ベース内でかなりローカライズされます。これが問題を引き起こす少数のクエリです。レポートはこの種の問題を引き起こす可能性がはるかに高く、データベース マネージャー全体で機能する一般的なレポート クエリを実行しても、うまく機能する可能性はほとんどありません。一部のアプリケーションは、他のアプリケーションよりも悲しみを引き起こす可能性が高くなります.

したがって、アプリケーションの「移植可能な」SQL コンストラクトに依存することが一般的なケースで機能する可能性は低いです。より良い戦略は、機能する一般的なステートメントを使用し、これが機能しないデータベース固有のレイヤーに分割することです。

一般的なクエリ メカニズムは、可能であれば ANSI SQL を使用することです。別の可能なアプローチは、さまざまなデータベース プラットフォームのドライバーを取得できる O/R マッパーを使用することです。このタイプのメカニズムは、大部分のデータベース操作には十分ですが、プラットフォーム固有の作業を行う必要があり、それが不足している場合があります。

より複雑な操作の抽象化レイヤーとしてストアド プロシージャを使用し、ターゲット プラットフォームごとにプラットフォーム固有の sproc のセットをコーディングできる場合があります。sproc には、ADO.net などからアクセスできます。

実際には、パラメーターの受け渡しと例外処理の微妙な違いが、このアプローチで問題を引き起こす可能性があります。より良いアプローチは、プラットフォーム固有のデータベース操作を共通のインターフェースでラップするモジュールを作成することです。使用している DBMS プラットフォームに応じて、さまざまな「ドライバー」モジュールを交換できます。

于 2010-01-08T13:08:57.203 に答える
3

Oracle には、純粋な SQL に変換することが不可能ではないにしても、非常に困難なモデル階層クエリなどの追加機能があります。

于 2010-01-08T12:43:10.817 に答える
1

SQL:2008で何かができる場合でも、構文が同じでない場合があります。たとえば、REGEXPマッチング構文を例にとると、SQL:2008はLIKE_REGEXMySQLと比較して使用しますREGEXP

そして、はい、私は同意します、それは非常に迷惑です。

于 2010-01-08T13:13:24.357 に答える
1

ここSOで共通

正確に答えるには:

ISNULL は、ここの回答/コメントに従って、データ型の優先順位により、SQL Server の COALESCE とは異なる結果を簡単に与えることができます。

于 2010-01-08T20:28:51.803 に答える
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 (式) 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 に答える