質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

Q&A

1回答

6093閲覧

PL/SQL テーブル名が可変なSQLをオープンせずに実行(暗黙オープン)できる?

tatatatao

総合スコア6

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

0グッド

0クリップ

投稿2016/12/21 01:47

編集2022/01/12 10:55

###前提・実現したいこと
Database linkを使用して、更新先のDBを動的に制御する必要があります。
まずは送信元DBと更新先DBの差を取得し、差があれば更新先DBを更新します。

現行は1つのサーバから1つのサーバへデータ連携していたので、差分取得の際、カーソル宣言をして、暗黙カーソルオープンされてました。
改修するにあたり、1つのサーバから複数のサーバへデータ連携する必要が出てきました。
そこでDBLINKを使用するのですが、テーブルを動的にするとなると、OPENしてFETCHすることが避けられない(と思っています)ようで、現行の処理を大幅に変更する必要がありますが、それを避けたいです。


ご回答ありがとうございます。
ソースの参考を貼り付けます。
スマホからなので、抜粋ですが、宜しくお願い致します。
###現行ソース(抜粋)

PL/SQL

1CREATE OR REPLACE procedure 2XX.ABC( 3 DB_LINK_NM varchar2(384); 4) as 5 6--差分取得カーソル変数 7cursol A 8 is 9select a,b,c 10 from TBL_A 11minus 12select a,b,c 13 from TBL_B; 14 15--更新処理 16procedure UPDATE_MST( 17 rec in A%ROWTYPE; 18) as 19 update TBL_A 20 set A = REC.a, 21 B = REC.b 22 where C = REC.c 23end UPDATE_MST; 24 25begin 26 --差分取得してLOOP 27 for REC in A loop 28 --更新処理 29 UPDATE_MST(REC); 30 end loop; 31... 32 33

###改修案(抜粋)

PL/SQL

1CREATE OR REPLACE procedure 2YY.ABC( 3 DB_LINK_NM varchar2(384); 4) as 5 6--変数定義 7SQL varchar2(1000); 8TYPE cv_type IS REF CURSOL; 9cur_cv cv_type; 10 11--差分取得SQL作成処理 12procedure CERATE_GET_DIF_SQL 13as 14 WSSQL varchar2(1000); 15begin 16 WSSQL := ''; 17 WSSQL := WSSQL ∣∣ 'select a,b,c from TBL_A'; 18 WSSQL := WSSQL ∣∣ 'minus'; 19 WSSQL := WSSQL ∣∣ 'select a,b,c from TBL_B@'; 20 WSSQL := ∣∣ DB_LINK_NM ; --◆ここで更新先テーブルのDBリンク名を結合 21 22open cur_cv for WSSQL 23 loop fetch cur_cv into REC(定義済変数とする) 24 exit cur_cv%NOTFOUND; 25 --〜更新処理(更新先DBをDBリンク名で指定して更新)〜 26 end loop; 27close cur_cv; 28...

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

OPENしてFETCHすることが避けられない、って意味がよくわかりません。
現状のコードを提示できますか?
SYNONYM を使ってDB LINK先を変更することは可能です。

投稿2016/12/21 02:04

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatatatao

2016/12/21 03:46 編集

初心者なもなで、シノニムの有効な使い方もわからず... リンク先を読んでみます。 ありがとうございます! また、簡単ではありますがソースを貼り付けました。 宜しくお願い致します。
Orlofsky

2016/12/21 04:20

プロいグラム・コードは </> で引用してください。 同じPL/SQLを同じスキーマのテーブルやDB LINK先で実行するのであれば、現行のコードをベースに CREATE OR REPLACE SYNONYM SYNONYM_NAME1 FOR USENAME1.TBL_B ; でTBL_BをSYNONYM_NAME1で PL/SQLを実行 CREATE OR REPLACE SYNONYM SYNONYM_NAME1 FOR USENAME1.TBL_B@dblinknm ; でTBL_B@dblinknmをSYNONYM_NAME1でPL/SQLを実行
tatatatao

2016/12/21 05:08 編集

ご指摘、ご回答ありがとうございます。 同じ場合はそう実装するのですね、勉強になります。 今回はdblink先が複数あり、その宛先がプロシージャに引数で渡ってきます。 その場合はどうしたら良いでしょつか?
Orlofsky

2016/12/21 17:43 編集

CREATE TABLE, CREATE INDEX など、コードが実行できるだけの物もいっしょに載せてください。コードも突っ込みどころがいっぱいです。 http://docs.oracle.com/cd/E57425_01/121/LNPLS/create_procedure.htm#i2072424 今回はparameter_declarationでDB_LINK_NAMEを使うと、PROCEDUREの中で動的SQL http://docs.oracle.com/cd/E57425_01/121/LNPLS/dynamic.htm#BHCEBBAI が必要になるので、無意味にプログラムが複雑になってしまいます。わたしが提示したようにシンプルに CREATE OR REPLACE SYNONYM を使われては? parameter_declarationを使うにしても桁数は記述しません。 コードをシンプルにする意味でcursol Aの記述方法は現行と同じで良いでしょう。 UPDATEはPRODEDUREにするのではなく、LOOPの中に直接書いた方がシンプルです。 SYNONYMが理解できていないようです。 http://www.shift-the-oracle.com/words/synonym.html 今回はプライベート・シノニムで良いでしょう。 複数のSESSIONから今回のPRODEDUREを同時に実行するなら、UPDATE の前にSELECT ... FOR UPDATE http://docs.oracle.com/cd/E57425_01/121/SQLRF/statements_10002.htm#i2065646 できちんと排他制御をする必要があります。 今、Oracle SQLやPL/SQLの勉強中でしょうか?納期が決まっている実務に着かれているなら、職場に教えを請えるメンバーが必要です。そういうメンバーがいなければ、熟練者を増員するか、Oracle SQL入門やPL/SQL基礎などの有償研修に行かないと難しいでしょう。 http://www.oracle.com/jp/education/promotion/course-flow-database.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問