• ベストアンサー

動的SQL

いつもお世話になってます。 ストアドで、動的SQLを行いたいのですが、イマイチ分かりません。 テーブルT1(文字列)から、項目K1(べた書き)の最大値、最小値を抽出し、変数A,Bに格納したいのですが、どうすればいいのでしょうか?? なお、テーブルT1がDBに存在することはチェック済みです。 よろしくお願いします。

  • Oracle
  • 回答数5
  • ありがとう数3

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

  • ベストアンサー
  • _tomo_
  • ベストアンサー率28% (2/7)
回答No.4

#2 の修正版です -- --------------------------------------------- -- 動的SQLの作成 -- --------------------------------------------- C_SQL := DBMS_SQL.OPEN_CURSOR; v_SQL := 'SELECT 項目1,項目2,項目3 FROM ' || i_TABLE_NM; -- --------------------------------------------- -- 動的SQLの解析 -- --------------------------------------------- DBMS_SQL.PARSE(C_SQL ,v_SQL , DBMS_SQL.NATIVE); FOR n_CNT IN 1..i_SU LOOP t_MOJI(n_CNT) := ''; DBMS_SQL.DEFINE_COLUMN(C_SQL,n_CNT,t_MOJI(n_CNT),100); END LOOP; -- --------------------------------------------- -- 動的SQLの実行 -- --------------------------------------------- Y := DBMS_SQL.EXECUTE(C_SQL); -- ------------------------------------------ -- フェッチ処理 -- ------------------------------------------ IF DBMS_SQL.FETCH_ROWS(C_SQL) = 0 THEN EXIT; END IF; -- ------------------------------------------ -- 値の取得 -- ------------------------------------------ DBMS_SQL.COLUMN_VALUE(C_SQL ,1 , x); --xに項目1の値が入る DBMS_SQL.COLUMN_VALUE(C_SQL ,1 , y); --yに項目2の値が入る DBMS_SQL.COLUMN_VALUE(C_SQL ,1 , z); --zに項目3の値が入る ------------------------------------------------- こんな感じ?

その他の回答 (4)

  • miko_zz
  • ベストアンサー率0% (0/1)
回答No.5

#3 全然意味違いでした。。。 なのでもうひとつの方法として書き方の簡単な方を アドバイスさせていただきます。 -------------------------------------------------- /* テストパッケージ定義 */ CREATE OR REPLACE PACKAGE TEST IS PROCEDURE TEST2(t1 in varchar ); END; / /* テストパッケージ本体 */ CREATE OR REPLACE PACKAGE BODY TEST IS PROCEDURE TEST2( t1 in varchar ) IS N_MAX_VALUE INT; -- 最大値 N_MIN_VALUE INT; -- 最小値 S_SQL varchar(256); BEGIN -- 実行するSQL文 S_SQL := 'SELECT MAX(K1), MIN(K1) FROM ' || t1 ; -- SQL実行と結果取得 EXECUTE IMMEDIATE S_SQL INTO N_MAX_VALUE, N_MIN_VALUE ; -- とりあえず結果をテストテーブルに格納 INSERT INTO TEST_RESULT( MAX_VALUE, MIN_VALUE, CREATE_DT ) SELECT N_MAX_VALUE, N_MIN_VALUE, SYSDATE FROM DUAL ; END TEST2; END; / /* テストプロシージャ実行 */ EXEC TEST.TEST2( 't1' ) ; /* テスト結果の表示 */ SELECT * FROM TEST_RESULT ; -------------------------------------------------- ただSQL解析時のオーバーヘッドが大きいとは聞いてますが、 多用しなければ問題ないと思われます。

  • miko_zz
  • ベストアンサー率0% (0/1)
回答No.3

始めまして。 miko_zzと申します。 ストアド内で値を取得して使用するのであれば、 下記のテストで確認することは出来ます。 -------------------------------------------------- /* テスト結果テーブル */ CREATE TABLE TEST_RESULT MAX_VALUE INT, MIN_VALUE INT, CREATE_DT DATE ) ; /* テストパッケージ定義 */ CREATE OR REPLACE PACKAGE TEST IS PROCEDURE TEST; END; / /* テストパッケージ本体 */ CREATE OR REPLACE PACKAGE BODY TEST IS PROCEDURE TEST IS N_MAX_VALUE INT; -- 最大値 N_MIN_VALUE INT; -- 最小値 BEGIN SELECT MAX(K1),MIN(K1) INTO N_MAX_VALUE,N_MIN_VALUE FROM T1; INSER INTO TEST_RESULT( MAX_VALUE, MIN_VALUE, CREATE_DT ) SELECT N_MAX_VALUE, N_MIN_VALUE, SYSDATE FROM DUAL ; END TEST; END; / /* テストプロシージャ実行 */ EXEC TEST.TEST ; /* テスト結果の表示 */ SELECT * FROM TEST_RESULT ; -------------------------------------------------- 違ってたらごめんなさい。

  • _tomo_
  • ベストアンサー率28% (2/7)
回答No.2

私は以下の方法で行っています -- --------------------------------------------- -- 動的SQLの作成 -- --------------------------------------------- C_SQL := DBMS_SQL.OPEN_CURSOR; v_SQL := 'SELECT * FROM ' || i_TABLE_NM; -- --------------------------------------------- -- 動的SQLの解析 -- --------------------------------------------- DBMS_SQL.PARSE(C_SQL ,v_SQL , DBMS_SQL.NATIVE); FOR n_CNT IN 1..i_SU LOOP t_MOJI(n_CNT) := ''; DBMS_SQL.DEFINE_COLUMN(C_SQL,n_CNT,t_MOJI(n_CNT),100); END LOOP; -- --------------------------------------------- -- 動的SQLの実行 -- --------------------------------------------- Y := DBMS_SQL.EXECUTE(C_SQL); -- ------------------------------------------ -- フェッチ処理 -- ------------------------------------------  IF DBMS_SQL.FETCH_ROWS(C_SQL) = 0 THEN EXIT; END IF; -------------------------------------------- だいたい、こんな感じです 参考になります?

hiro_sun
質問者

お礼

なんとなくは分かるんですが、この場合select文で取得したデータはどこに格納されてれるんですか??

回答No.1

こんにちは。 やり方はいろいろ(大きく2通り)ありますが、どれがいいですか? 1.IMMIDEATEを使用 2.DBMS_SQLパッケージを使用 それぞれ特徴(後の処理にも)があります。 (^^ゞ

hiro_sun
質問者

お礼

さっそくのお答え有難うございます。 ですが・・・それぞれの特徴がわからないのでなんとも・・・ スミマセン!!

関連するQ&A

  • 抽出した行数を変数に入れたい(オラクルSQL)

    SELECTで抽出した行数を変数に格納したいのですが、上手くいきません。 SQLにあまり経験がなく、ネットで調べながら実践しております。 例えば以下の簡単なSQLを作ったとして、 ---------------------------------------------------- SELECT a,b,c,d,e,f FROM table WHERE c=10 AND e=20; ---------------------------------------------------- ここで抽出した行数を取得し、それを変数に入れたいと思っております。 というのも、後々、抽出したデータの行数を表示したい場合に SELECT COUNT(*) FROM table WHERE c=10 AND e=20; というSQLをその都度入力していては非効率だと思ったからです。 そこで抽出する際に行数を取得し、それを変数に格納して、 行数を表示する処理が今後必要になった際に、その変数を表示すれば良いと考えました。 ですがネットで変数のことを調べた際に VARやDEFINE等のコマンドを見つけましたが、SQLを実行しても上手くいきません。 最初に記載したSQLに、どのような構文を入れたら良いのでしょうか。

  • SQL・・・分かりません。

    SQLの勉強をしています。 仕事の研修で習っているのですが、基礎的なものを学習しましたが 応用したパターンが全く理解ができません。 例としまして ・AテーブルとBテーブルを結合して、データを抽出する ・Aテーブルに存在しているのに、Bテーブルに存在していないデータも抽出する ・しかし、Aテーブルに存在していないのに、Bテーブルに存在しているはデータは抽出しない ☆抽出方法に二パターン存在する 1つ目も全く見当つかずです。ヒントでよいので教えていただけたらと思います。 意味が分からなかったらすみません。何を描き足したらよいか教えて下さい。 宜しくお願いしたします。

  • SQL文で

    SQL2000serverで 異なる2つのデーターベースの中にある 別のテーブルの情報を SQL文を使って、抽出する事は出来るのでしょうか? たとえば下記のように「DB-A」「DB-B」と言った 二つのDBの中のそれぞれのテーブルのIDフィールドで リレーションを取ってDB-AのTablA1のFldAの 値(AA)からDB-BのTablB1のFldBの値(あ)を 抽出することはSQL文で可能なのでしょうか? DB-A DB-B TablA1 TableB1 ID FldA ID FldB 1 AA 1 あ 2 BB       2 い 3 CC 3 う 4 DD 4 え

  • 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を超えるような文字列を格納できたり、                    他の良い方法はあるのか?

  • SQLについて教えてください

    お世話になっております。 以下、取得したい内容です。 この内容に対して、どのようにSQLを書けばよいか良いか教えて頂きたいです。 (1)DBの全テーブルに対して特定のカラムを取得したい。(カラム名はA,Bとする) (2)取得したカラム.Aに格納されている各値に対して、カラム.Bの各レコードの項目には何の値が格納されているか知りたい。 DBはオラクルですが、オラクルでしか使えないSQL構文はつかないようにしたいです。 自分で考えたSQLは、 SELECT A,B FROM * GROUP BY A,B ですが、そもそも全テーブルを指定する際に使用するのが、「*」では正しくないような気もします。 説明がつたなくて申し訳ございません。 宜しくお願い致します。 ・テーブルイメージ テーブル.test1 +--------+------+ | No | A | B | +--------+------+ | 01 |AA| 1 | | 02 |AA| 1 | | 03 |AB| 2 | | 04 |AB| 2 | | 05 |AC| 3 | | 06 |AC| 3 | | 07 |AC| 3 | +--------+------+ テーブル.test2 +--------+------+ | No | A | B | +--------+------+ | 01 |AA| 1 | | 02 |AA| 1 | | 03 |AB| 2 | | 04 |AB| 2 | | 05 |AC| 1 | | 06 |AC| 3 | | 07 |AC| 3 | +--------+------+ テーブル.test3 +--------+------+ | No | A | B | +--------+------+ | 01 |AA| 3 | | 02 |AA| 1 | | 03 |AC| 2 | | 04 |AC| 3 | +--------+------+

  • sqlのJoinでこんなこと出来ますか、

    sqlのJoinでこんなこと出来ますか、 当方初心者につき宜しく御願いします。 テーブルAにはIDがありIDはユニークです。テーブルBにはIDと項目がありIDは複数件存在します。項目には「あ」又は「い」、「う」、「え」、「を」が入っています。idに対して「あ」だけの時もあれば、「い」、と「う」が存在する時もあります。1件または複数件存在します。 条件に「あ」を抽出するようにして、「あ」がないときは存在するがテーブルBには存在するという結果を作りたいのです。 ID=1、あ ID=2、NULL という結果を作りたいのです。テーブルの双方に存在して、かつ「あ」であれば「あ」以外はNULLのレコードを作りたいのです。 説明が悪くて申し訳ありませんが宜しく御願い致します。

    • ベストアンサー
    • MySQL
  • PL/SQLの初歩的な質問

    失礼します。 PL/SQLについて、初歩的な質問をさせてください。 DBに以下のような文字列が入っていて、 それを抽出し変数にセットするとします。 A'1234567'→変数aにセット B'  12A345B'→変数bにセット 質問1 Aの文字列を取得した際、'123-4567'のように 間にハイフンを付けて変数aにセットする場合 どのようなPL/SQLの記述になりますか? 質問2 Bの文字列を取得した際、'12345'のように 左側の空欄と数字以外の文字を取り、 なおかつ数字を半角にして変数bにセットする場合 どのようなPL/SQLの記述になりますか? お手数お掛けしますが ご回答宜しくお願いします。

  • SQL初心者です。ご教授願います。

    SQL初心者です。ご教授願います。 テーブルAとテーブルBの比較をしたいと思っています。 比較するのは、全項目(もしくは、特定の項目でもかまいません)です。 どなたか、SQLのアドバイスをお願いします。  条件   ・DB: Microsoft SQLserver2000   ・テーブルAとテーブルBの項目は同じ(コピーして作られたもの)です。   ・比較は全項目です(キー項目の有無も含まれます)。   

  • SQL文での条件分岐

    列a,b,cから構成されるテーブルAが存在します。 これをテーブルB(列d,e)に以下の流れでコピーしたいのです。 ・a列の値 → d列 にコピー ・aの値が"1"ならば、b列の値 → e列 にコピー / "1"以外は、c列の値 → e列 にコピー としたいのですが、これをSQL文だけで書けますか? ストアドを書くのであれば、どのような感じで書けばいいのでしょうか? ヒントだけでも結構ですので、分かる方はお教えいただけますか?

  • T-SQLの sp_executesql について

    SQL-Serverでストアドプロシージャを作っています。 EXEC sp_executesql で検索結果をテーブル型変数に格納したいですができるのでしょうか。動的にSQLを発行し、結果を格納する必要がありますのでEXEC sp_executesqlを使わざる得ない状況です。下記にそのサンプルがあります。 Declare @tblAA Table(NO int) declare @strSQL nVarChar(1000) set @strSQL = '' set @strSQL = @strSQL + ' Insert into @tblAA' set @strSQL = @strSQL + ' Select NO from TBLBango' EXEC sp_executesql @strSQL ,N'@tblAA table(No int) OUTPUT', @tblAA OUTPUT Select * from @tblAA これを実行すろと「変数 '@tblAA' を宣言する必要があります。」というエラーがでます。 解決方法を分かる方教えてください。