プロが教える店舗&オフィスのセキュリティ対策術

Oracle11gのPL/SQLで動的SQLを使おうと思うのですが、下記エラーが発生してしまいます。
どこが間違っているのか、いろいろと変更してみたのですが、わかりませんので、教えてください。

「ORA-06502:PL/SQL:数値または値のエラー:文字から数値への変換エラー。が発生しました」

ワークのテーブルを一旦削除してから、新規に追加し、データを登録する処理です。

EXECUTE IMMEDIATE 'DROP TABLE AAA_WK';
EXECUTE IMMEDIATE 'CREATE TABLE AAA_WK AS SELECT * FROM AAA WHERE SUBSTR(REPLACE(STRDATE, '/' ,'') ,1 ,6) > ' || ls_month_max;
EXECUTE IMMEDIATE 'TRUNCATE TABLE AAA';
EXECUTE IMMEDIATE 'INSERT INTO AAA SELECT * FROM AAAA_WK';

STRDATE:文字列の日付~時刻が入っています(例:2016/09/10 12:10:10)
ls_month_max:'201608'の文字列です

2つ目のEXECUTE IMMEDIATEでエラーが発生します。
ある年月(201608)より大きいデータを取得したいです。
TO_NUMBERにして変数も数値型にして書いてもダメでした。
変数(ls_month_max)をシングルコートで囲ってもダメでした。

相談できる人がいないため、よろしくお願いいたします。

質問者からの補足コメント

  • HAPPY

    自己解決しました。
    変数のところではなく、REPLACEしている箇所のシングルコーテーションをエスケープ(?)していないのが原因でした。

    EXECUTE IMMEDIATE 'CREATE TABLE AAA_WK AS SELECT * FROM AAA WHERE SUBSTR(REPLACE(STRDATE, ''/'' ,'''') ,1 ,6) > ''' || ls_month_max || '''';

    ちなみにCREATE文の場合、バインド変数は使えないようです。

      補足日時:2016/10/07 15:03

A 回答 (2件)

STRDATEってのは、本当に文字列(VARCHAR2型など)ですか?


DATE型なら、TO_CHAR(STRDATE, 'YYYYMM')としないとダメですよ。

SELECT SUBSTR(REPLACE(STRDATE, '/' ,'') ,1 ,6)
FROM AAA
で返ってきてる値は正しいですか?

また、テーブル列を加工するとインデックスが効きません。
要件にもよりますが、やるなら
STRDATE BETWEEN 開始日 AND 終了日
とかの方がいいと思います。
あと、ここにあるように、SQLの解析が都度発生するため、プレースホルダーを利用したクエリにした方がいいでしょう。
http://www.shift-the-oracle.com/plsql/native-dyn …

一度きり、およびそこまでパフォーマンスが気にならないデータ量ならどうでもいいです。
    • good
    • 0
この回答へのお礼

> STRDATEってのは、本当に文字列(VARCHAR2型など)ですか?

はい、VARCHAR2です。
登録日時を文字列型で持っています。

> SELECT SUBSTR(REPLACE(STRDATE, '/' ,'') ,1 ,6) FROM AAA

これは通ります。

select * from AAA
where SUBSTR(REPLACE(STRDATE, '/' ,'') ,1 ,6) > '201608'

これでデータが取得できます。

記載いただいたURLを参考に、バインド変数にしてみましたが、同じ結果でした。


ls_sql := 'CREATE TABLE AAA_WK AS SELECT * FROM AAA WHERE SUBSTR(REPLACE(STRDATE, '/' ,'') ,1 ,6) > :"month"';

EXECUTE IMMEDIATE ls_sql USING IN ls_month_max;

お礼日時:2016/10/04 16:05

テーブルAAAと、AAA_WKの構造が違うんじゃないんですか?


条件はともかくとして、
CREATE TABLE AAA_WK AS SELECT * FROM AAA
で通るんですか?
    • good
    • 0
この回答へのお礼

naktakさん

ありがとうございます。

CREATE TABLE AAA_WK AS SELECT * FROM AAA
これは実行できています。

WHERE句をなくして
EXECUTE IMMEDIATE 'CREATE TABLE AAA_WK AS SELECT * FROM AAA'

とすると、実行でき、データも入ってきますので、WHERE句の部分がおかしいようです。

お礼日時:2016/10/04 14:14

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

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