web-dev-qa-db-ja.com

副作用のある標準SQL関数はありますか?

SQL標準は副作用のある関数を定義していますか?

たとえば、それらに ファイルへの書き込み *の関数があるか、または次のようなことをしたときにテーブルの特定の列の値を更新しますか?

SELECT myfunction(params...);

これらを時々見たことがありますが、SQL標準が同じことをしているのかどうか知りたいだけです。


*これは特にPostgreSQLに関する質問ではありません。私はPostgreSQLで見られる副作用の例のみを使用しています。

11
tinlyx

ここにはいくつかの質問があります。

Q:ANSI標準SQL関数とは何ですか?

ANSI標準関数は、AVG、COUNT、MIN、MAXなどです。それらは 1992 ANSI規格 でカバーされていますが、それは乾燥した退屈な読み物の1つです。

Q:ANSI標準SQL関数はデータベースのデータを変更しますか?

いいえ。これらを使用してデータを変更できます。たとえば、次のように言うことができます。

INSERT INTO dbo.MyReport SELECT MAX(SalespersonRevenue) FROM dbo.Sales

しかし、それ自体では、AVG、COUNT、MIN、MAXなどを使用しても、データベース内のデータが永続的に変更されることはありません。

Q:ANSI標準では、独自の関数を記述できますか?

はい。ただし、正確な実装はベンダーごとに異なります。作成する関数はANSI言語標準に準拠している場合がありますが、関数内で行うことは、副作用を作成するなど、恐ろしくひどい場合があります。

  • 意図した動作について議論するとき、クロスプラットフォームの回答を得ることが可能です。
  • 副作用について議論するときは、そうではありません。

Q:データを書き込む独自の関数を作成できますか?

あなたが創造的であるならば、なぜ確かです。私はMicrosoft SQL Serverの人なので、そのプラットフォームに焦点を当てます。 Books Onlineの機能ページ は次のように述べています。

ユーザー定義関数を使用して、データベースの状態を変更するアクションを実行することはできません。

私が言うには:

あなたは私の本当のお父さんではありません。

だからここに私がルールを破る方法があります。警告:非常に悪い考えが続きます。

  • 関数で、この邪悪な目的のために特別に作成された新しいテーブルにクエリを実行し、テーブルの選択ステートメントを監視してアクション(拡張イベント、監査、またはプロファイラートレース)を起動するものを作成します。 Rube Goldbergのような仕掛けをフックして、これらの選択ステートメントに基づいて作業を実行できます。
  • 関数では、CLRコードを呼び出します-えっと、あなたは Webサービスを呼び出す さえできます。そのWebサービスは、データを独自のデータベースにプッシュバックすることができます。
  • 関数では、xp_cmdshellを呼び出します で、コマンドプロンプトから何かを行います。 (コメント内のHT @AaronBertrand。)

これらすべての例には、パフォーマンスとトランザクションの一貫性という形で大きな欠点があります。あなたは理論的にそれが可能かどうか尋ねたところ、その答えはイエスです。私は自分のコードでこれらのいずれも使用することはありません-私は戻って尋ねます、「私がここで達成しようとしているビジネス目標は何ですか、そしてパフォーマンスとトランザクションの一貫性を達成するためにそれを行うことができる方法はありますか? ?」それらについて具体的なアドバイスが必要な場合は、詳細を含む別のスタック質問をします。

18
Brent Ozar