回答:
ストアドプロシージャを通常のSQLと混在させることはできませんが、ストアドファンクションを混在させることはできます。
たとえばSELECT get_foo(myColumn) FROM mytable
がget_foo()
プロシージャの場合は無効ですget_foo()
が、関数の場合はそれを実行できます。その代償として、関数にはプロシージャよりも多くの制限があります。
プロシージャと関数の最も一般的な違いは、それらが異なる方法で、異なる目的で呼び出されることです。
ルーチン作成の構文は、手順と関数で多少異なります。
関数は値を返すので、関数定義には戻り値のデータ型を示すRETURNS句が必要です。また、呼び出し元に値を返すには、関数本体内に少なくとも1つのRETURNステートメントが必要です。RETURNSおよびRETURNは、プロシージャー定義には現れません。
ストアドプロシージャを呼び出すには、を使用しCALL statement
ます。ストアドファンクションを呼び出すには、式で参照します。関数は、式の評価中に値を返します。
プロシージャはCALLステートメントを使用して呼び出され、出力変数を使用してのみ値を返すことができます。関数は、他の関数と同じように(つまり、関数の名前を呼び出すことによって)ステートメント内から呼び出すことができ、スカラー値を返すことができます。
パラメーターをIN、OUT、またはINOUTとして指定することは、PROCEDUREに対してのみ有効です。FUNCTIONの場合、パラメーターは常にINパラメーターと見なされます。
パラメーター名の前にキーワードが指定されていない場合、それはデフォルトでINパラメーターです。 ストアード関数のパラメーターの前には、IN、OUT、またはINOUTがありません。すべての関数パラメーターはINパラメーターとして扱われます。
ストアドプロシージャまたは関数を定義するには、それぞれCREATE PROCEDUREまたはCREATE FUNCTIONを使用します。
CREATE PROCEDURE proc_name ([parameters])
[characteristics]
routine_body
CREATE FUNCTION func_name ([parameters])
RETURNS data_type // diffrent
[characteristics]
routine_body
ストアドプロシージャ(関数ではない)のMySQL拡張は、プロシージャが結果セット、または複数の結果セットを生成できることです。これらは、呼び出し元がSELECTステートメントの結果と同じ方法で処理します。ただし、そのような結果セットの内容を式で直接使用することはできません。
ストアドルーチン(ストアドプロシージャとストアドファンクションの両方を指す)は、テーブルやビューと同じように、特定のデータベースに関連付けられています。データベースを削除すると、データベース内のストアドルーチンもすべて削除されます。
ストアドプロシージャと関数は同じ名前空間を共有しません。データベースに同じ名前のプロシージャと関数を含めることができます。
ストアドプロシージャでは、動的SQLを使用できますが、関数やトリガーでは使用できません。
SQL準備済みステートメント(PREPARE、EXECUTE、DEALLOCATE PREPARE)は、ストアード・プロシージャーで使用できますが、ストアード関数またはトリガーでは使用できません。したがって、ストアドファンクションとトリガーはダイナミックSQLを使用できません(ステートメントを文字列として作成し、実行する場合)。(MySQLストアドルーチンの動的SQL)
FUNCTIONとSTORED PROCEDUREのさらに興味深い違い:
(このポイントはブログ投稿からコピーされます。)ストアドプロシージャは、関数が含まれていないプリコンパイルされた実行プランです。実行時に解析およびコンパイルされる関数。ストアドプロシージャ。データベースに擬似コードとして格納されます(つまり、コンパイルされた形式)。
(この点
についてはわかりません。)ストアドプロシージャはセキュリティが確保されており、ネットワークトラフィックを軽減します。また、ストアドプロシージャをどの番号でも呼び出すことができます。一度にアプリケーションの。参照
関数は通常、計算に使用されますが、プロシージャは通常、ビジネスロジックの実行に使用されます。
ストアドプロシージャを使用してコミットなどのデータベースの状態に影響を与えることができるのに対し機能は、データベース(明示的または暗黙的なコミットか、またはロールバック機能で禁止されているステートメント)の状態に影響を与えることができない
refrenceを:J.1を。ストアドルーチンとトリガーの制限
関数はFLUSHステートメントを使用できませんが、ストアドプロシージャは使用できます。
ストアドプロシージャは再帰可能ですが、ストアドファンクションは再帰的ではありません。注:再帰ストアード・プロシージャーはデフォルトで無効になっていますが、サーバーでmax_sp_recursion_depthサーバー・システム変数をゼロ以外の値に設定することで有効にできます。詳細については、セクション5.2.3「システム変数」を参照してください。
ストアドファンクションまたはトリガー内では、関数またはトリガーを呼び出したステートメントによって(読み取りまたは書き込みのために)既に使用されているテーブルを変更することはできません。良い例:MYSQLで削除時に同じテーブルを更新する方法は?
注:通常、一部の制限はストアドファンクションとトリガーに適用されますが、ストアドプロシージャには適用されませんが、ストアドファンクションまたはトリガー内から呼び出された場合、それらの制限はストアドプロシージャに適用されます。たとえば、ストアドプロシージャでFLUSHを使用できますが、そのようなストアドプロシージャは、ストアドファンクションまたはトリガーから呼び出すことはできません。
重要な違いの1つは、SQLクエリに関数を含めることができることですが、ストアドプロシージャはCALL
ステートメントでのみ呼び出すことができます。
UDFの例:
CREATE FUNCTION hello (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)
CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');
SELECT hello(name) FROM names;
+--------------+
| hello(name) |
+--------------+
| Hello, Bob! |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)
Sprocの例:
delimiter //
CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)
delimiter ;
CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World! |
+---------------------------+
1 row in set (0.00 sec)
RETURNS CHAR(50) DETERMINISTIC
?
RETURNS CHAR(50)
状態は、データの種類が返されます。RETURN CONCAT(...
返されるデータです。両方が必要です。DETERMINISTIC
基になるデータが変更されない状態に必要とされています。