SQL標準は副作用のある関数を定義していますか?
たとえば、ファイルに書き込むための関数や、次のような場合にテーブルの特定の列の値を更新する関数がありますか?
SELECT myfunction(params...);
これらを時々見たことがありますが、SQL標準が同じことをしているのかどうか知りたいだけです。
*これは特にPostgreSQLに関する質問ではありません。私はPostgreSQLで見られる副作用の例のみを使用しています。
SQL標準は副作用のある関数を定義していますか?
たとえば、ファイルに書き込むための関数や、次のような場合にテーブルの特定の列の値を更新する関数がありますか?
SELECT myfunction(params...);
これらを時々見たことがありますが、SQL標準が同じことをしているのかどうか知りたいだけです。
*これは特にPostgreSQLに関する質問ではありません。私はPostgreSQLで見られる副作用の例のみを使用しています。
回答:
ここにはいくつかの質問があります。
Q:ANSI標準SQL関数とは何ですか?
ANSI標準関数は、AVG、COUNT、MIN、MAXなどです。それらは1992年のANSI規格でカバーされていますが、これは無意味で退屈な読み物です。
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の機能ページには次のように書かれています。
ユーザー定義関数を使用して、データベースの状態を変更するアクションを実行することはできません。
私が言うには:
あなたは私の本当のお父さんではありません。
だからここに私がルールを破る方法があります。警告:非常に悪い考えが続きます。
これらの例にはすべて、パフォーマンスとトランザクションの一貫性という形で大きな欠点があります。あなたは理論的にそれが可能かどうか尋ねたところ、その答えはイエスです。私は自分のコードでこれらのいずれも使用することはありません-戻って質問します、「私がここで達成しようとしているビジネス目標は何ですか、そしてパフォーマンスとトランザクションの一貫性を達成するためにそれを実行できる方法はありますか? ?」それらについて具体的なアドバイスが必要な場合は、詳細を含む別のスタック質問をします。
私はSQL Serverに関して明確に話すことができるだけで、これはすべてのデータベース実装にわたって一貫していないようです。ただし、SQL Serverでは、関数は副作用を生成しない場合があります。これは、何度も回避しようとして成功しなかった厳格な規則です。
一般的な意味で関数について考えている場合、副作用(たとえば、ストアドプロシージャ)を許可するSQLモジュールがありますが、ユーザー定義関数は許可しません。
特にマイクロソフト製品に当てはまる「賢いソリューションは拡張しない」という言葉があります。MSが真の機能として追加したため、SQL Serverの初期のバージョンでいくつかの巧妙な回避策が見られました。
機能にならないもの、正直に言えば、T-SQL開発の一部の側面を根本的に壊したため、機能にならないもの。関数の副作用はその1つです。