PLSQLでSQLの実行に関する質問

このQ&Aのポイント
  • PLSQLを使用してSQLを実行する際に、VARCHAR2(32767)で宣言した変数の文字数を超えるエラーが発生しています。SQLを結合する際に変数の最大文字列を超えてしまっているため、1度のSQLで実行する方法を探しています。
  • 配列の数分だけUNIONでSQLを結合し、変数に格納しているため、配列の量が多いと変数の最大文字列を超えてしまいます。処理速度や既存のプログラムの変更を避けつつ、1度のSQLで実行する方法を教えてください。
  • 現在、PLSQLを使用してSQLを実行している際にエラーが発生しています。変数の文字数制限を超えてしまうため、1度のSQLで処理する方法を探しています。配列の条件によって抽出条件が変わるため、変数を分割することやSQLを再構築することは避けたいです。良い方法があれば教えてください。
回答を見る
  • ベストアンサー

PLSQLでのSQLの実行に関しての質問

[環境] db:oracle 11g express edition os:windowsXP 言語:PLSQL [質問] PLSQLを使用したプログラムを作成していたのですが、SQLの文字数がVARCHAR2(32767)で宣言した変数の文字数を超えてしまいエラーとなります。 理由としては、引数で受け取った配列の数分だけUNIONでSQLを結合し、変数に格納しているのですが、配列の量が多いと変数の最大文字列を超えてしまうようです。(ソースイメージは下記に記述) 対応としては、変数を分割し、SQLを実行することや、SQLを組みなおすなどの対応が考えられるのですが、”(1)処理速度の都合上、できれば1度のSQLで実行したい。”、”(2)抽出条件が配列の条件によって、複雑に変わることと、既に稼働しているプログラムの為あまりソースを変更したくない”という理由から検索条件は変えずに、1度のSQLでどうにか実行できないかと考えています。 上記条件をクリアする何か良い方法はありますでしょうか? (もし、1回のSQLで実行は難しいのであれば、最悪配列を使用してSQLを分割して対応しようとは思っています。ただ、他に方法があるのであればそれに越したことはないです。) どなたか良い方法をご存知の方がおりましたら教えていただけないでしょうか? 宜しくお願い致します。 [ソースイメージ] <引数> 配列[100];          <-- 条件が格納された配列 <変数定義部> hensu_union VARCHAR2(32767); <-- 結合したSQLを格納 hensu_where VARCHAR2(1000); <-- SELECTの条件の格納 <プログラム部>  <省略>  .  .  .   FOR i IN 1..配列分 LOOP <-- 配列の数分、UNIONでSQLを結合 IF i > 1 THEN hensu_union := hensu_union || 'union '; END IF; hensu_union := hensu_union || 'select A,B,C .... from マスタA、マスタB WHERE ' || hensu_where ;  ←ここのUNIONで結合しすぎると最大文字列を超えエラー  END LOOP; . .  省略 . .   OPEN カーソル名 FOR hensu_union ; ←SQLを実行する部分でどうにか1回で済ませたい。                    VARCHAR2を超えるような文字列を格納できたり、                    他の良い方法はあるのか?

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.1

SQLが長くなりすぎること自体を解消できたほうがいいのでしょうが、 詳細な内容が分からないので、プログラム的な解決方法です。 Oracle11gから動的SQLで実行するSQLにCLOB型を使用することができるようになっています。 http://docs.oracle.com/cd/E16338_01/appdev.112/b56260/whatsnew.htm#CHDGIGFJ ですので、hensu_unionをVARCHAR2ではなくCLOBにすれば文字列長の制限を回避できるのではないかと思います。

関連するQ&A

  • PLSQLで変数に格納されたSQL文の実行

    お世話になります PLSQLで変数に格納されたSQL文を実行するにはどうしたらよいでしょうか? vSql := 'select count(*) from XXX_tbl;' で vSql を実行させたいです。 ご教授ください。

  • PLSQLエラー

    こんにちわ。 いまORACLE10GでPLSQLを修正しています。 そこいま,PLSQLのなかで,SQL文を格納する変数を LONG型で定義していますが, SQL文字列を連結していくなかで, エラー番号-6502になってしまいます。 ちなみに6502とは「演算、数字、文字列、変換、制約条件などにエラー」 だとか… コーディングのなかに思い当たる節がありません。 このエラーは何が原因なんでしょうか? 教えてください。 宜しくお願いします。

  • PLSQLで条件によりSQLを動的に変えたい

    例えば、あらかじめテーブルなどを読み、その内容により、 SQLの文そのものを非常に変えたいとします。 SQLその1 select * from TABLEA where A = 1 SQLその2 select * from TABLEA where A = 1 and B = 2 and C = 3 and D = 4 上記は例ですが、内容などにより複雑な条件式を追加したい。 ベースのSQLは非常に長い為、 例えば 完全に切り分けるのでは無く、共通の部分は共通ソースとしたい。 また、プリプロセッサみたいに、条件式が追加された場合 あたかも、初めからそのSQLのみがあり、他の制御文などをSQL文自身には追加したくない。 動的SQLでは無い方法でそのような事が可能でしょうか? ----- イメージ ----- select * from TABLEA where A = 1 IF (条件がある時のみ) B = 2 and C = 3 and D = 4 END IF; ------------------- 実際には、SQL文の中にPLSQLの制御文をうまく追加できない。

  • InterBase(firebird)で固定文字列と文字列型フィールドのunionでエラー

    お世話になっております。 InterBase(firebird)のunionについての質問です。 あるテーブル(test_table)に test_cd VARCHAR(2) ; というような、文字列があるとします。 これを単純に抽出するSQL と、固定文字列を値の代用とするSQL をunionで求めようとした際に、以下のSQLで問い合わせました。 select test_cd from test_table where [条件] union select '00' test_cd from test_table where [条件] 問い合わせた際に以下のようなエラーが返ってきました。 Dynamic SQL Error SQL error code = -104 Invalid command Data type unknown それぞれのSQLは正しく返ってくるのですが、 unionで結合した際にこのエラーが返ってきます。 どのように対処すればよいのでしょうか、 ご回答をよろしくお願いいたします。

  • ストアド内で実行したSQLの出力結果について

    現在、引数の値を元に下記のようなSQL文を生成しています。 SELECT code, name FROM T_CGY WHERE code = '1111' UNION SELECT code, name FROM T_CGY WHERE code = '1110' UNION SELECT code, name FROM T_CGY WHERE code = '1100' UNION SELECT code, name FROM T_CGY WHERE code = '1000' ORDER BY code; ※出力されたSQL文に誤りがないかを確認する為にコピーしてターミナル上で実行したら該当するレコードを取得する事ができました。 それをストアドプロシージャ内で生成したSQL文を「QUERY EXECUTE」を実行して該当するレコードが取得できるように改造してみました。 下記が出力された結果です。 getCgyData -------------------- (1000,洋服) (1100,子供服) (1110,ズボン) (1111,長ズボン) 出力されたデータは私が望んだ内容なんですが・・・ 私的には下記のように出力したいと考えています。 col1    | col2 ------------------------- 1000  | 洋服 1100  | 子供服 1110  | ズボン 1111  | 長ズボン 何とか上記のように出力できるようにするにはどうしたらいいでしょうしょうか。 そもそも上記のように出力する事は可能なのでしょうか。 CREATE FUNCTION getCgyData (VARCHAR) RETURNS TABLE(col1 VARCHAR, col2 VARCHAR) AS ' DECLARE key ALIAS FOR $1; sql TEXT; BEGIN                 ・                 ・ ※ここでSQL文を生成して、変数(sql)に格納しています。                 ・                 ・ RETURN QUERY EXECUTE sql; END; ' language 'plpgsql' ; データベースのバージョンはpostgreSQL8.4.9です。 再度、申し訳ありませんがアドバイス、宜しくお願いします。 では、失礼します。

  • プログラミングPHP内でのSQL文に関するご質問

    プログラミングのPHPの学習中です。 掲示板に関するプログラミングで下記の様なソースコードが記述されていました。 (usersテーブルのusernameとpasswordとセッション変数のusernameとpasswordが等しいという条件の下、情報を抽出するというSQL文です。) $sql = "select * from users where username = '".$_SESSION["username"]."' and password='".$_SESSION["password"]."'"; 上記ソースコードでご質問です。 '".$_SESSION["username"]."'と、'".$_SESSION["password"]."'の箇所で、セッション変数をダブルクォーテーションで囲んでいるのは、変数展開するためと理解しました。また、更にシングルクォーテーションで囲むのは、変数展開したものを文字列として扱う為と理解しました。しかし、セッション変数の両隣にあるピリオドの意味がよく分かりません。文字列と変数を結合する為だと思うのですが、府に落ちません。 どなたかお教え頂ければ幸いです。 何卒宜しくお願い致します。

    • ベストアンサー
    • PHP
  • PL/SQLで…SQLの実行結果を変数を格納する方法

    毎度お世話になります。 SQL文の実行結果を変数に格納する方法がわからず困っております。 ご存知の方が居られましたらご教示いただきたい所存です。 常に1つの値しか返さないようなSQL文なので 変数V number := 'select count(B列) from B表'; みたいな書き方はで 入るか見てみようと思ったのですが コンパイルはできるものの、 実行すると「文字から数値への変換エラー。が発生しました」と なって上手くいきませんでした。 'select count(B列) from B表'が単なる文字列として解釈されて エラーになっているのだとは思うものの 正しい書き方がわからないのでよろしくお願いいたします。

  • PLSQLのバインド変数の件です。

    こんにちわ。 いま,VBからテーブル名と列名をバインド変数としてPLSQLに渡しました。 そこで,PLSQLのなかで, v_Sql := 'UPDATE :Table_Name SET :Column_Name = :After_Change_Value WHERE :Column_Name = :Before_Change_Value ' ; のようにSQLを組み立て, DBMS_SQL.PARSE(v_Cursor, v_Sql, DBMS_SQL.NATIVE); でSQLを解析したところ,ERR-903となってしまいます。 ちなみに,:Table_Nameと:Column_Nameにテーブル名と列名をそのまま記述したところ,上記のエラーはパスできます。 VBからPLSQLにテーブル名と列名を変数として渡して,PLSQLのなかでSQLを解釈するにはどうすれば良いでしょうか? 教えてください。 宜しくお願いします。

  • PL/SQL

    PL/SQL(Oralce)で、NVARCHAR2の変数を宣言した場合、その変数への代入方法を教えてください。 Hensu NVARCHAR2; と宣言し、 Hensu := N'テスト'; とした場合、コンパイルエラーとなりませんが、 Hensu  NVARCHAR2; Hsensu1 VARCHAR2; と宣言し、 Hensu := N || Hsensu1; とした場合、”識別子Nを宣言してください。”旨のコンパイルエラーが出力されていしまいます。 OracleはR8.1.7です。 よろしくお願いします。

  • UNION ALLのように順番がありNULLを返す方法

    SQL初心者です。ACCESSデータベースに対するクエリを書いているのですが、 条件を配列として、その配列の順番に応じたSELECT文を書きたいのです。 SELECT * FROM access_db WHERE ID = '条件' UNION ALL SELECT * FROM access_db WHERE ID = '条件' UNION ALL SELECT * FROM access_db WHERE ID = '条件' UNION ALL... といった具合にSQL文を作成しているのですが、これでは見つからない条件がある場合に、行が繰り上がり条件を格納した配列とはずれが生じてしまいます。 見つからなかった場合にNULLまたはそれを表せる何かを抽出結果として組み込むことはできますか? SQL初心者のためUNION ALL程度しか近いものが見つけられなく、困っています。 どなたかよろしくお願いします。

専門家に質問してみよう