• 締切済み

PL/SQL データ型チェックについて

PL/SQLでSPを作成しています。 その中で 「数値だったらA処理をして、数値ではなかったらB処理をする」 という箇所があるのですが、データ型のチェックをするような関数は見つからず、どうしようか悩んでいます。 今、とりあえず「to_number」で変換をしてみて、エラーにならなければA処理、エラーになればB処理とする、という方法は思いついたのですが、例外エラーって遅くなりそうな気がしてあまり使いたくないなと思います。 何かいい方法はないでしょうか?

みんなの回答

  • utakataXEX
  • ベストアンサー率69% (711/1018)
回答No.1

バージョンがわかりませんが、正規表現を使う方法も あります。 但し、個人的には、to_numberでexceptionで拾うのと比較 して、極端に速度的な差が出るとは思えません。 http://www.atmarkit.co.jp/fdb/rensai/sqlclinic01/sqlclinic01_1.html

参考URL:
http://www.atmarkit.co.jp/fdb/rensai/sqlclinic01/sqlclinic01_1.html

関連するQ&A

  • PL/SQLって?

    今日からPL/SQLの本を読み始めたド素人です。。。 ありえない質問かもしれませんがどなたか助けてください! 今SQL*Plusに参考本の通り以下のコードを記述したところ エラーが発生してしまいました。 通常のSQL文とは違い普通にSQL*Plus上にコーディングするだけでは うまく機能しないのですか? それとも何か設定が必要だったりするのでしょうか? 参考本には特にそのような記述もなくサイトなどから調べても 自分ひとりではどうも解決できません。 ご協力よろしくお願いします! SQL> PROCEDURE PROC_A( 2 a IN NUMBER 3 b IN NUMBER, 4 c OUT NUMBER) 5 /  ↓  エラー内容  ↓ PROCEDURE PROC_A( * 行1でエラーが発生しました。: ORA-00900: SQL文が無効です。

  • PL/SQLでのSQLエラーログの出力について

    PL/SQLでのSQLエラー発生時のログ出力について教えていただきたいことがあります。 既存のシステムで、メインからAの処理を呼び出し、さらにAからBの処理を呼び出している処理で、 エクセプション処理がメインにしか記述されていないものがありました。 この場合、処理Aや、処理BでSQLでエラーが発生した時は、 メインでエラーログが出力されると思いますが、 何か特定特別なケースの場合、きちんと異常が認識できない等の問題はないでしょうか? お手数をおかけしますが、よろしくお願いします。

  • PL/SQLについての質問です。

    PL/SQLについての質問です。 カーソルデータ(emp_rec(i))を、TABLE変数(emp_ins(i))に代入して、代入されたTABLE変数を使用して、DML処理を行うことは可能ですか? エラーを解読し対処を行っても、エラーが発生してしまいます。 どうか、ご教授お願いします。 下記を実行すると、下記エラーが発生します。 -実行結果------------------------------------ DECLARE * 行1でエラーが発生しました。: ORA-06502: PL/SQL: 数値または値のエラーが発生しました ORA-06512: 行127 -エラー番号解読----------------------------------------- ●エラー名: PL/ SQL: 数値または値のエラーstring が発生しました ●原因: 算術、数値、文字列、変換または制約エラーが発生しました。たとえば、NULL 値をNOT NULL で宣言した変数に割り当てようとした場合、または100 以上の整数をNUMBER( 2) で宣言した変数に割り当てようとした場合にこのエラーが発生します ●処置:値が制約違反をしないように、データ、操作方法または宣言方法を変更してください。 -ソース------------------------------------ DECLARE --カーソル定義 CURSOR emp_cur IS SELECT a,b,c FROM emp TYPE emptabtype IS TABLE OF emp%ROWTYPE INDEX BY PLS_INTEGER; emp_rec emptabtype; /* 処理対象データ格納変数 */ -- insert作業用 emp_ins emptabtype; ins_count NUMBER := 1; BEGIN /* empカーソルオープン・フェッチ・クローズ */ OPEN emp_cur; FETCH emp_cur BULK COLLECT INTO emp_rec; CLOSE emp_cur; /* (挿入)処理対象のデータを、処理対象データ格納変数に格納する。 */ FOR i IN emp_rec.FIRST..emp_rec.LAST LOOP --挿入するレコードを格納 emp_ins(ins_count) := emp_rec(i); ins_count := ins_count + 1; END LOOP; /* DML処理 */ -- 挿入する FOR count_ins IN emp_ins.FIRST..emp_ins.LAST LOOP INSERT INTO temp VALUES(emp_ins(count_ins).a ,emp_ins(count_ins).b ,emp_ins(count_ins).c); END LOOP; COMMIT; END; /

  • PL/SQLを使用した、プログラミング方法について

    今、独学でPL/SQLについて学習しているのですが、下記の問題が解けません。。。 考えても、自分の答えが出ないので質問させてください。 ------------------------------------------------------------ 下記の表(temp表)をPL/SQLのカーソルを使い取得しました。 temp表:主キー=No ------------------ No,ID, 処理, 数値 1 , A, 加算(1), 1000 2 , A, 加算(1), 500 3 , A, 減産(2), 500 4 , A, 加算(1), 100 ----------------- 5 , B, 加算(1), 200 6 , B, 減産(2), 100 7 , B, 加算(1), 50 ------------------ 8 , C, 加算(1), 100 9 , C, 減産(2), 50 ※加算の場合、値は「1」減算の場合、値は「2」です。 (1)その後、取得した値を使って、ID別の数値残高を計算したいです。 「加算」「減算」の区別は、「処理」カラムを使って区別をつけたいです。 例:ID「A」の数値残高 = 1000+500-500+100   ID「B」の数値残高 = 200+100-50 (2)1つのIDの計算が終了したら、次のIDの計算が始まる。 例:ID「A」の数値残高が計算終了→ID「B」の残高計算開始→ID「C」の残高計算開始 (3)その後、(2)で計算した値を、ほかのテーブル(answer)に挿入したいです。 例: answer表 ID, 数値残高 -------------- A, 1100 B, 150 C, 50 このような処理をPL/SQLを使って、実装したいのですが。 (1)(2)(3)の処理を教えて頂けないでしょうか? ※1つのIDあたり、1万レコードを持っています。 パフォーマンス(処理速度)も考えて、プログラミングしたいです。 もし、カーソルを使って表を取得する意外に、よい方法があるならば、そちらの方法でも可能です。 ご教授・ご回答よろしくお願いします。質

  • SQL*Plus内でPL/SQL、SQLを実行するシェルスクリプトを書

    SQL*Plus内でPL/SQL、SQLを実行するシェルスクリプトを書いています。 イメージ sqlplus scott/tiger << EOF   declare     aaa number;   begin     -- *1     select col1 into aaa from test1;   end;   /   -- *2   define a=1   define b=1   @test.sql EOF ここで*1にて例えば複数行が返ってくるなどのエラーが 発生した場合、*2以降のSQLを実行せずにSQL*Plusから抜けたいのですが どのようにすればよいかわかりますでしょうか。 whenever sqlerror exit 255 などはPL/SQL内の論理エラーはハンドリングしてくれないようです。 よろしくお願いします。 それかdefineや@マーク指定によるsqlファイルの取り込みを PL/SQLの中で実行できる方法を教えていただく方法でも 当方が実施したいことはできるのでそれでもかまいません。

  • oracleのPL/SQLのEXIT戻りでエラーが

    PL/SQLを実行したのですが、EXITの終了でエラーがとなってしまいます。エラーがでます。 being~endを書いてしてPL/SQLを実行しているのですが、 being~endのPL/SQLでエラーとなった場合、EXITの終了時の戻りで以下のエラーがでます。 エラーとならないようにするにはどうしたらよいでしょうか。 SP2-0670: 内部数値変換が失敗しました。 使用方法: { EXIT | QUIT } [ SUCCESS | FAILURE | WARNING | n | 変数 | :バインド変数 ] [ COMMIT | ROLLBACK ] 実行したSQLは以下となります。 set serveroutput on exec utl_file.fremove('DATA_PUMP_DIR','hogehoge.txt'); VARIABLE rtn NUMBER DECLARE BEGIN :rtn := 0; select count(*) from d; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||','||SQLERRM); :rtn := 16; END; / EXIT :rtn →ここでエラーがでる oracleは19cです。 よろしくお願いします。

  • うまくPL/SQLが書けません。

    PL/SQLを作成しているのですが、うまくいかないので 質問させていただきました。SQL初心者ですがよろしければご教示ください。 テーブル名  カラム名 Bar       number numberには’AB734869 テスト’、‘AB364850 再テスト’ といった具合にまず8桁の番号が入り、その後データによってテキスト項目が続いています。 そしてnumberのデータへ、一律、頭から数えて5バイト目と6バイト目の間に’0000’という文字列を挿入したいと考えています。 例えば’AB734869 テスト’の場合は’AB7300004869 テスト’というようにしたいのですが、良い方法が思いつきません。 STUFF関数は使えませんし。。。UPDATEやINSERTを使ってやろうと思ったのですが、 どうしても出来ません。 皆様の知恵を拝借頂けたらと幸いです。 宜しくお願いいたします。 m(_ _)m

  • PL/SQLでの文字列と数値の比較について

    いつもお世話になっております。 次のように、今が午前中なら「AM」と表示するPL/SQLのプログラムを考えています。 BEGIN if TO_CHAR(SYSTIMESTAMP,'hh24')<12 THEN DBMS_OUTPUT.PUT_LINE('AM'); END if; END; / 動作しているように見えるのですが、TO_CHARはVARCHAR2型を返すとマニュアルに書いてありました。TO_CHARが返す値は数値に変換したほうがよいのでしょうか。あるいはPL/SQLでも、文字列は数値に変換されるのでしょうか。 お教えいただけると助かります。 何卒よろしくお願いいたします。

  • SQL Server において

     いつも大変お世話になっています。  早速質問させていただきます。  SQL SERVER で、数値演算を行いたいのですが、 どれが演算子になっているのかがよく分かりません(- -; 「+」だと文字列演算になってしまい、ならば、数値型に変換してからやればいいのだ!!とおもい、TO_NUMBER関数を使ったところ関数とは認識されませんでした(T T)。 一体どうすればいいのでしょうか?お願いします。教えていただきたいです。 Oracleの関数が使えない場合があるので、SQL SERVER で使用できる関数が載っているサイトなどがあったら教えていただきたいです。

  • PL/SQLでの処理について

    キーの異なる2つのトランザクションテーブルA,Bに マスタCの値を引っ張ってきて各A,B埋める処理を、テーブル名を引数にPL/SQLのプロシージャにしたいのですが、良い方法はありますか? 以下のイメージです。 <TABLE A> KEY_A C_CD C_VALUE -----+----+------- 1 3 2 3 3 1 <TABLE B> KEY_B C_CD C_VALUE -----+----+------- 1 3 2 3 3 1 <TABLE C> C_CD C_VALUE ----+-------- 1 A 2 B 3 C SQL>EXECUTE foo('A'); <TABLE A> KEY_A C_CD C_VALUE -----+----+------- 1 3 C 2 3 C 3 1 A SQL>EXECUTE foo('B'); <TABLE B> KEY_B C_CD C_VALUE -----+----+------- 1 3 C 2 3 C 3 1 A <処理イメージ> CREATE OR REPLACE PROCEDURE FOO(TNAME VARCHA2) IS c_cd NUMBER; C1 INTEGER; SQL1 VARCHAR2(2000); I INTEGER; BEGIN SQL1 := 'SELECT c_cd FROM ' || tname; C1 := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(C1, SQL1, DBMS_SQL.V7); DBMS_SQL.DEFINE_COLUMN(C1, 1, c_cd); LOOP IF DBMS_SQL.FETCH_ROWS(C1) > 0 THEN DBMS_SQL.COLUMN_VALUE(C1, 1, c_cd); UPDATE tname set value = c_cd; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ↑ここの部分をうまくかけないでしょうか? ELSE EXIT; END IF; END LOOP; end /

専門家に質問してみよう