Open Source WEB

今日から新年である。しかし、ファンクションを作ろうとしたとき、 エラーが出てしまったが、その解決は年を超えてしまった。

そのときのエラーメッセージを再録しておく。

ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or 
READS SQL DATA in its declaration and binary logging is enabled (you *might* 
want to use the less safe log_bin_trust_function_creators variable)

色々なことがごちゃごちゃ書かれているのだが、 DETERMINISTIC, NO SQL or READS SQL DATA の部分は、どうも関数を定義するときの指定が不足していることを 指しているものと推定できるではないか。

ここで、基本に戻って、関数定義を 17.2.1. CREATE PROCEDURE and CREATE FUNCTIONで調べてみることにする。

PROCEDUREとFUNCTIONの両方が書かれているので、 FUNCTION部分だけを以下に抜きだした。

CREATE FUNCTION sp_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...] routine_body
func_parameter:
    param_name type

type:
    Any valid MySQL data type

characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

routine_body:
    Valid SQL procedure statement

characteristic: の個所に、エラーメッセージ中にあったものが確かに並んでいる。 これらが足りないのであろう。

ここでは、DETERMINISTIC に注目してみよう。 そもそも、DETERMINISTICって何だろう。

長い説明なので、ブラウザの検索でDETERMINISTICを探したら、以下で引っかかった。

A procedure or function is considered “deterministic” if it 
always produces the same result for the same input parameters, 
and “not deterministic” otherwise. If neither DETERMINISTIC 
nor NOT DETERMINISTIC is given, the default is NOT DETERMINISTIC.

引数が同じなら結果も同じ場合が DETERMINISTIC であり、 引数が同じでも結果が同じとは限らない場合が NOT DETERMINISTIC のようだ。

作ろうとした関数 hello()は、

CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hello, ',s,'!');

であり、"Hello, " の後に入力された文字を入れ、さらに "!"を繋げて出力 するだけのものであり、入力が同じなら出力も同じになるので DETERMINISTIC である。

ということで、DETERMINISTIC を routinebody である RETURN CONCAT('Hello, ',s,'!') の直前に挿入してみた。

mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
    -> DETERMINISTIC RETURN CONCAT('Hello, ',s,'!');
    -> //
Query OK, 0 rows affected (0.00 sec)
 
mysql>

ちゃんと登録できたようだ。 DELIMITERを ; に戻してから、hello()呼び出して確認してみよう。

mysql> DELIMITER ;
mysql> SELECT hello('Asakusa');
+------------------+
| hello('Asakusa') |
+------------------+
| Hello, Asakusa!  |
+------------------+
1 row in set (0.00 sec)
 
mysql>

呼び出しての確認もできた。

まだ日本語には関係ない部分であるが、今日はここまでとしよう。


戻る:ファンクションを作ってみよう

次へ:日本語文字列を返すファンクションを作ってみよう


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us