Forum Stats

  • 3,854,882 Users
  • 2,264,431 Discussions
  • 7,905,823 Comments

Discussions

複数のselect結果を出力するには?

852764
852764 Member Posts: 14
edited Apr 14, 2011 4:38AM in SQLとPL/SQL
こんにちは 教えてください

従来SYBASEで開発をしており
最近Oracle(11g - r2)に移行しようと考えています。

そこで問題になっているのが
SYBASEでは ストアドプロシジャにて

create proc get_startup
as
--マスタXXX読み込み
 select aaa,bbb from XXX
--マスタYYY読み込み 
 select * from YYY
--マスタZZZ読み込み
 select NNN,PPP from ZZZ where flag = '1'

みたいな形で startup時に読み込むマスタ群を 一つのSPにまとめて管理しているのですが
ORACLEではこういうことは出来ないのでしょうか???

oracleのREF CURSORで outputできそうなんですが
それだとJDBCで受け取るのが非常に難しく 他にいい方法がないか
よろしければ 教えて頂けないでしょうか?

よろしくお願いします

Edited by: 849761 on 2011/04/04 18:22
Tagged:
«1

Answers

  • weyk
    weyk Member Posts: 82
     えーっと、SYBASEではどうなるのか、想像が付きません。そのため、じゃぁ、Oracleでどうするのか というのも答えようがありません。
    SYBASEとOracleの両方を知っている人にだけ通じればよいというのであれば別ですが、そうでは無い場合、「それによってどんな動作になるのか」を書かないと、わからないのではないかと思います。
    (そもそも、「スタートアップ時に読み込む」という必要性もわからないし、それがどう「管理」になるのかもわからない・・・)

    「SYBASEのよくあるプロシジャーの組み方」が、「Oracleでよくあるプロシジャーを組む場合」とぜんぜん違っていて、そもそも、組み方そのものを考え直さないといけないのでは・・・という気がします(混ぜると、大抵、残念なものが出来上がります。動的に(クエリを定義する感覚で)VIEWの生成と削除を繰り返すMS-ACCESSの組み方をしてしまった、Oracleのアプリケーション とか。)
    -- CMN v0.61β --
  • 852764
    852764 Member Posts: 14
    こんにちは

    >SYBASEではどうなるのか、想像が付きません

    やっぱりそうですよね どう書くのがいいのか
    かなり悩んだのですがそもそもSYBASEがどういう結果をもたらすのか
    両方使った人しか わからないですよね

    うーん例えば・・ SQLplusを起動しますよね
    そこで プロシジャを実行する場合を想像して頂けますか?

    SYBASEの場合だと 上記プロシジャを実行すると

    1>exec get_startup
    2>go
    (SYBASEでは goで実行されます)

    AAA BBB
    --------------------
    〇〇 XX
    〇〇 XX
    (2 rows affected)
    F
    --------------------



    (3 rows affected)
    NNN PPP
    --------------------
    〇〇〇 XXXX
    〇〇〇 XXXX
    〇〇〇 XXXX
    〇〇〇 XXXX
    (4 rows affected)
    1>

    とoutputlineを書いたりせずに 上記のようなデータが検索されて
    画面表示されます。
    こう言うことが oracleでは簡単に作れないのでしょうか?

    ということで 伝わりますでしょうか??
  • NN8さん、こんにちは。

    Javaですと、ResultSetとREFカーソルを紐付けて扱うことが可能です。
    http://www.oracle-base.com/articles/misc/UsingRefCursorsToReturnRecordsets.php
    が参考になると思います。引用例でのREFカーソルはひとつだけですが、複数のResultSetを扱いたい場合はストアドプロシージャのOUTパラメータを増やしてください。

    SQL*Plusだと、以下のような感じでバインド変数を利用することで対応可能です。
    SQL> variable d_cur refcursor
    SQL> variable e_cur refcursor
    SQL> call ref_cur_test(:d_cur, :e_cur);
    
    コールが完了しました。
    
    SQL> print d_cur
    
        DEPTNO DNAME                        LOC
    ---------- ---------------------------- --------------------------
            10 ACCOUNTING                   NEW YORK
            20 RESEARCH                     DALLAS
            30 SALES                        CHICAGO
            40 OPERATIONS                   BOSTON
    
    SQL> print e_cur
    
         EMPNO ENAME
    ---------- --------------------
          7369 SMITH
          7499 ALLEN
          7521 WARD
          7566 JONES
          7654 MARTIN
    ちなみに呼び出したストアドのソースは以下の通りです。
    create or replace procedure ref_cur_test(
      dept_ref_cur out sys_refcursor,
      emp_ref_cur out sys_refcursor
    ) is
    begin
      open dept_ref_cur for select * from dept;
      open emp_ref_cur for
        select empno, ename from emp where rownum < 6;
    end;
    /
  • 852764
    852764 Member Posts: 14
    >Javaですと、ResultSetとREFカーソルを紐付けて扱うことが可能

    やはり REFカーソルですか・・
    いろいろ調査しているのですが
    汎用的なメソッドをクライアント側に用意して
    なんとか 受け取りたいと思っているのですが
    敷居が高いです(汗)

    やっぱりoracle開発者の方は このような場合
    一個一個SQLでマスタを読み込まれるのでしょうか?
    SYBASEをやっていると すごく面倒に感じます・・

    とはいえ ORACLEにするメリットがあるんで
    (DBLINK&SYNONYMで別システムに
     データを書き込めるので
     処理速度がかなり上がります)
    やらなければならないのですが・・
  • weyk
    weyk Member Posts: 82
    「なにが便利なのか」(で、それができないから面倒なのか)がわからないです。おそらくは、「思いもしない機能」があるんだとは思いますが・・・「その後、どの部分で便利に使えるのか、それをしないと、どうなってしまい、不便なのか」がわからないので、あまりメリットに感じていません(「事前にマスタを読み込む処理」を使ったことが無いです。なので、そのインターフェースが汎用だと便利で、汎用にできないと不便・・・という感覚も無いですし、そのためにプロシジャを造るという感覚も無いです(個々のテーブルへのアクセスなら、通常のqueryで十分ですから))

    (どんな便利そうな機能があるのかは、個人的にはものすごく気になります。)
    -- CMN v0.61β --
  • 830749
    830749 Member Posts: 36
    edited Apr 6, 2011 11:19PM
    deleted

    Edited by: Seven on 2011/04/07 12:19
  • 852764
    852764 Member Posts: 14
    こんばんは
    >「なにが便利なのか」
    そうなんですよね お付き合いのあるデベロッパさんに聞いても
    みんな?が出ています(汗)

    >おそらくは、「思いもしない機能」

    そうですね 意識としては
    プロシジャもSQL文と同じ動きをしてくれるので
    プロシジャ内で select すれば それを実行した時に
    select結果が帰ってくる だけなんです
    (ただ SQLがコンパイル済みでDBに登録されているだけという感じ)

    でもOracleだと プロシジャ内で selectしても
    それを実行しても 普通に帰ってこないのが 逆に ??なんです

    >どんな便利そうな機能

    これは便利な機能ではないですが

    あるテーブルにカラム追加したとします
    そのテーブルを検索しているSQLが クライアントのプログラムとして多数あった場合
    1)まずそのテーブルの使われている箇所をクライアントプログラムから探す
    2)見つかった全てを修正する
    3)テスト

    という感じだと思うのですが

    それが プロシジャにまとめられていると
    1)プロシジャ内で使われている箇所を探す
    2)見つかったプロシジャを修正する
    3)テスト
    と 探す場所や修正漏れが減ると思うのですが どう思われますか?

    でもデベロッパさんに聞いても プログラム全部探します! って言われます(汗)
  • 827071
    827071 Member Posts: 31
    でもOracleだと プロシジャ内で selectしても
    それを実行しても 普通に帰ってこないのが 逆に ??なんです
    「普通」、「常識」は人によって違うので「普通と違う」と言ったところで「仕様か設計思想が違うだけじゃね?」としか思わないけど
    サイベースからスピンオフしたというSQL Serverだと「普通」に沿っているのかたどってみてもいいかも。
    それで「普通との違い」について納得いくのかどうかはわからんけど。
  • Blueloco
    Blueloco Member Posts: 118
    横槍にて失礼します。
    とoutputlineを書いたりせずに 上記のようなデータが検索されて
    画面表示されます。
    こう言うことが oracleでは簡単に作れないのでしょうか?
    出力結果の例と上記発言を見ると、「SELECT文の結果を標準出力したいだけなら、
    PROCEDUREなんか使わずにSQL*PlusからSQLスクリプトを読み込ませれば
    いいだけなのでは?」と思えてしまいました。

    たぶん見当はずれな意見なのだと思いますので、

     ・この処理の目的は何ですか?
     ・どのような出力結果が必要ですか?
     ・出力結果をどのようにしたいですか?

    を明確にした上で、それをOracleで実現するにはどうすればよいか?
    という聞き方をした方が話が早いのではないでしょうか。
  • 830749
    830749 Member Posts: 36
    edited Apr 9, 2011 9:38AM
    SQL Serverのスクリプト実行ツールは、SQL*Plusに相当するものはSQLCMD.exe等ですが
    そのツールでのストアド実行時の挙動に違いがあるというだけのことではないでしょうか。

    SQLCMDならget_startupを実行すればSELECT結果がコンソールに自動的に出力されますが、
    SQL*Plusではも正常ならコンソールには何も出力されません。
    結局、SQL*Plusでも「自動的にコンソール出力できないか」ということをお訊ねのようですが
    結論は、そういう機能はありません、ということになります。
    どうしてもコンソール出力が必要なのであれば、ご自分で最初の投稿にも書かれてらっしゃる
    ように、結果を出力する処理を追加する必要があります。

    SQL ServerとOracleの機能的な違いは他にもたくさんありますから、早々に次のステップへ
    移られることをお薦めします。

    Edited by: Seven on 2011/04/09 22:38
This discussion has been closed.