説明
CREATE FUNCTION ステートメントは、ストアド関数を作成するために使用されます。
権限要件
CREATE PROCEDURE ステートメントを使用するには、CREATE FUNCTION 権限が付与されている必要があります。
例:
ユーザーに権限 CREATE ROUTINE を付与すると、ユーザーは FUNCTION を作成できるようになります。
mysql> GRANT CREATE ROUTINE ON my.* TO mingye;
mysql> DELIMITER //
mysql> CREATE FUNCTION db.add_numbers(a INT, b INT)
-> RETURNS INT
-> BEGIN
-> RETURN a + b;
-> END //
デフォルトでは、PROCEDURE が作成されると、OceanBaseデータベースは自動的に ALTER ROUTINE および EXECUTE 権限をルーチン(ストアドプロシージャおよび関数)の作成者に付与します。DEFINER 句が存在する場合、必要な権限は user の値によって決まります。
構文
CREATE
[DEFINER = user]
FUNCTION [IF NOT EXISTS] sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
func_parameter:
param_name type
type:
Any valid MySQL data type
characteristic: {
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}
routine_body:
Valid SQL routine statement
デフォルトでは、ストアドファンクションはデフォルトのデータベースに関連付けられています。ストアドファンクションを指定されたデータベースに関連付けるには、database_name.sp_name を使用して名前を指定します。
ストアドファンクションを呼び出すには、式でその関数を参照します。この関数は式の評価時に値を返します。
DEFINER および SQL SECURITY 句は、ルーチン実行時にアクセス権限をチェックするために使用するセキュリティコンテキストを指定します。
IF NOT EXISTS は、既に存在する同名のルーチンの作成を防ぎます。ストアド名が組み込みSQL関数の名前と同じ場合、ルーチンを定義する際または後でルーチンを呼び出す際に名前とその後の括弧の間にスペースを使用しない限り、構文エラーが発生します。したがって、既存のSQL関数の名前を使用してユーザー自身のストアドルーチンを作成することは避けてください。
括弧内の proc_parameter パラメータリストは常に存在する必要があります。パラメータがない場合は、空のパラメータリストを表すために空の括弧 () を使用します。ここでのパラメータ名は大文字と小文字を区別しません。ストアドファンクションの各パラメータは IN パラメータです。
RETURNS 句はストアドファンクション専用であり、関数の戻り値の型を指定するために使用されます。関数本体には RETURN value ステートメントを含める必要があります。RETURN ステートメントが異なる型の値を返す場合、その値は適切な型に強制的に変換されます。たとえば、関数が RETURNS 句で ENUM または SET 値を指定しているにもかかわらず、RETURN ステートメントが整数を返す場合、関数から返される値は SET メンバーセット内の対応する ENUM メンバーの文字列です。
パラメータ型と関数の戻り値型は、任意の有効なデータ型として宣言できます。CHARACTER SET が先頭に付いている場合は、COLLATE プロパティを使用できます。
routine_body は有効なSQLステートメントで構成されます。SQLステートメントは、SELECT または INSERT のような単純なステートメントである可能性があります。または、BEGIN と END で記述された複合ステートメントである可能性があります。複合ステートメントには、宣言、ループ、およびその他の制御構造ステートメントを含めることができます。実際には、ストアドファンクションは複合ステートメントを使用する傾向がありますが、本体が単一の RETURN ステートメントで構成されている場合は例外です。
ストアドルーチン内で USE ステートメントを使用することは許可されていません。ルーチンを呼び出すと、USE database_name が暗黙的に実行され(ルーチン終了時に取り消され)、ルーチンの実行にデフォルトのデータベースが指定されます。ルーチンのデフォルトデータベース以外の他のデータベースオブジェクトを参照する場合は、データベース名を使用して限定することができます。
厳密なSQLモードでルーチンを定義しても、非厳密モードで呼び出される場合、ルーチンのパラメータには厳密モードで値が代入されません。厳密なSQLモードでルーチンに渡される式を割り当てる場合は、ルーチンを厳密モードで呼び出す必要があります。
COMMENT プロパティはストアドルーチンを説明するために使用でき、SHOW CREATE PROCEDURE および SHOW CREATE FUNCTION ステートメントを使用してコメント情報を表示できます。
LANGUAGE プロパティは、ルーチンを記述するために使用される言語を示します。これはSQLルーチンにのみ適用され、サーバーはこのプロパティを無視します。
ルーチンが常に同一の入力パラメータに対して同一の結果を生成する場合、それは「決定的」と見なされます。そうでない場合は、「非決定的」と見なされます。ルーチン定義に DETERMINISTIC または NOT DETERMINISTIC がどちらも指定されていない場合、デフォルトは NOT DETERMINISTIC です。関数を決定的であると宣言するには、明示的に DETERMINISTIC を指定する必要があります。
ルーチンがデータを使用するプロパティに関する詳細は以下のとおりです:
CONTAINS SQLは、ルーチンにデータの読み書きを行うステートメントが含まれていないことを示します。これがデフォルトです。たとえば、SET@x=1またはDO RELEASE_LOCK('abc')は実行されますが、データの読み取りや書き込みは行いません。NO SQLは、ルーチンにSQLステートメントが含まれていないことを示します。READS SQL DATAは、ルーチンにデータの読み取りを行うステートメント(たとえばSELECT)が含まれていることを示しますが、データの書き込みを行うステートメントは含まれていません。MODIFIES SQL DATAは、ルーチンにデータの書き込みを行う可能性のあるステートメント(たとえばINSERTまたはDELETE)が含まれていることを示します。
SQL SECURITY は DEFINER または INVOKER であり、ルーチンが指定されたアカウント(このアカウントにはルーチンに関連付けられたデータベースへのアクセス権限が付与されている必要があります)の権限で実行されるか、呼び出し元の権限で実行されるかを指定します。デフォルト値は DEFINER です。ルーチンを呼び出すユーザーには、そのルーチンに対する EXECUTE 権限が付与されていなければなりません。
DEFINER 句は、ルーチンの実行時にルーチンのアクセス権限をチェックするために使用されるアカウントを指定します。DEFINER 句が存在する場合、user 値は 'user_name'@'host_name' として指定されたアカウント(たとえば 'admin'@'oblocalhost')または CURRENT_USER() 関数によって取得されたアカウントである必要があります。DEFINER 句を省略した場合、デフォルトの定義者は CREATE FUNCTION ステートメントを実行したユーザーです。SQL SECURITY DEFINER プロパティを使用して定義されたストアドルーチンの本体では、CURRENT_USER 関数を使用してルーチンの DEFINER 値を返すことができます。
サーバーは、ルーチンのパラメータ、DECLARE で作成されたローカルルーチン変数、または関数の戻り値のデータ型を次のように処理します:
データ型の不一致やオーバーフローが存在するかどうかをチェックします。変換とオーバーフローの問題は、厳密なSQLモードで警告またはエラーを引き起こします。
スカラー値のみを指定できます。たとえば、
SET val=(SELECT 1, 2)ステートメントは無効です。文字データ型について、宣言に
CHARACTER SETが含まれている場合は、指定された文字セットとそのデフォルトの照合順序が使用されます。COLLATEプロパティが使用されている場合は、デフォルトの照合順序ではなく、指定された照合順序が使用されます。CHARACTER SETとCOLLATEが存在しない場合は、ルーチンの作成時に適用されたデータベースの文字セットと照合順序が使用されます。サーバーがデータベースの文字セットと照合順序を使用するのを回避するには、パラメータに明示的にCHARACTER SETとCOLLATEプロパティを指定してください。データベースのデフォルトの文字セットまたは照合順序を変更するには、新しいデータベースのデフォルト値を適用するために、ストアドルーチンを削除して再作成する必要があります。
character_set_databaseおよびcollation_databaseシステム変数は、データベースの文字セットと照合順序を指定するために使用できます。
関数の作成方法の詳細については、ストアドファンクションを参照してください。