アプリ版:「スタンプのみでお礼する」機能のリリースについて

PostgreSQLでストアドファンクションを作成しました。

ファンクションの内容は下記の通りです。
CREATE FUNCTION getRenban (VARCHAR) RETURNS VARCHAR(7) AS
'
DECLARE
key ALIAS FOR $1;
code VARCHAR(7);
code2 VARCHAR(2);
code5 VARCHAR(5);
renban INTEGER;
new_code VARCHAR(7);

BEGIN
SELECT MAX(code) INTO code FROM M_ITEM WHERE flg = TRIM($1);
code2 := TRIM($1);

IF code IS NULL THEN
renban := 1;
ELSE
SELECT SUBSTR(code, 2) INTO code5;
SELECT TO_NUMBER(code5, ''99999'') INTO renban;
renban := renban + 1;
END IF;

code5 := '''';
SELECT TO_CHAR(renban, ''00000'') INTO code5;
SELECT code2 || code5 INTO new_code;

RETURN new_code;
END;
'
language 'plpgsql'
;

コンソール上で下記のコマンドを実行したらエラーが出力されました。
SELECT getrenban('01');

出力されたエラーの内容は下記の通りです。
ERROR: value too long for type character varying(5)
CONTEXT: PL/pgSQL function "getrenban" line 19 at SQL statement

お恥ずかしいですがいくらコードを見てもどこが原因なのかわかりません。
申し訳ありませんがご教授お願いできませんでしょうか。
昨日から悩んでいます。
どうか助けて下さい、宜しくお願いします。

A 回答 (2件)

>ERROR: value too long for type character varying(5)


>CONTEXT: PL/pgSQL function"getrenban" line 19 at SQL statement

line 19と言う事は

code5 := '''';
SELECT TO_CHAR(renban, ''00000'') INTO code5;


この辺ですよね。
で、「長過ぎてvarchar(5)に入れられない」と怒られています。

PL/pgSQLは実務で使った事がないのですが、オラクルのPL/SQLの観点で回答します。

5桁の数字が入ったintegerの変数をTO_CHARすると結果は6桁になります。
+-が一桁付加されるからです。
(正の場合は半角スペース)

なので「長過ぎてvarchar(5)に入れられない」と怒られたわけです。

代入時にスペースをトリムすれば解決します。

それと、クリア時のダブルクォートが気になりましたが、コンパイルが通っているので、これは問題無いのでしょうね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

知りませんでした。
結果が6桁になるなんて・・・
大変、勉強になりました。

本当に助かりました、ありがとうございました。

お礼日時:2012/02/16 23:24

1点気になりましたが、複数セッ


ションからの同時アクセスに
ついての要件はどうなっています
でしょうか?

これだと同時アクセスの際に、
運が悪ければ同じ連番になって
しまいます。

通常はこの手の場合、シーケンス
オブジェクトを使用します。
(重複する事なく、カウントアップ
できます)

要件的に許されるのであれば、今
の作りでもよいですが、そうで
なければ、シーケンスの使用を
検討してください。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す