• ベストアンサー

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を解釈するにはどうすれば良いでしょうか? 教えてください。 宜しくお願いします。

  • Oracle
  • 回答数2
  • ありがとう数4

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

  • ベストアンサー
回答No.2

こんにちは。 No.1さんのおっしゃるとおりです・・・。 v_Sqlが文字列なので、「:Table_Name」というテーブル名はおかしいですよね? カラム名も同様です・・・。 v_Sql := 'UPDATE' || Table_Name || 'SET' || Column_Name || '=' || After_Change_Value 単純に変数を展開して、文字列のSQLを作ってください・・・。 (^^ゞ

tatsurou
質問者

お礼

taka451213さん こんにちわ。 教えてもらった方法でできました。 ありがとうございました。

その他の回答 (1)

回答No.1

ホスト変数を使って、テーブル名や項目を可変要素にすることは出来ません。 ホスト変数を使わずに、直にSQL文にテーブル名や項目名を展開した上で DBMS_SQL.PARSEしてください。

tatsurou
質問者

お礼

k_o_r_o_c_h_a_n さん こんにちわ。 ありがとうございます。 教えてもらった方法でできました。

関連するQ&A

  • 変数が選択リストにありません

    変数が選択リストにありません 下記のコードを実行すると「変数が選択リストにありません」というエラーが出てしまいます。 SELECT文とFETCHのINTOの変数の個数が一致していない場合にこのエラーは出るということらしいのですが、問題ないように思うのです。 下記コードで何が問題になっているのか教えてください。 よろしくお願いします。 set serveroutput on; declare -- 各テーブルの全カラムを取得 cursor curcol (p_tblname user_tables.table_name%type) is select COLUMN_NAME,DATA_TYPE from user_tab_columns where table_name = p_tblname ; v_sql varchar2(1000); -- SQL文 v_col varchar2(1000); -- カラム名 v_val varchar2(1000); -- 取得データ v_tblname varchar2(20); -- テーブル名 v_RstExec integer; v_CursorID integer; begin v_col := ''; v_tblname := 'sample'; -- 取得テーブルのカラムを取得 for rowcol in curcol(v_tblname) loop -- 取得カラムをCSV形式に変換 if v_col is null then v_col := rowcol.COLUMN_NAME; else v_col := v_col||'||'',''||'||rowcol.COLUMN_NAME; end if; end loop; dbms_output.put_line(v_col); -- SQL作成 v_sql := 'select '||v_col||' from '||v_tblname; v_CursorID := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(v_CursorID, v_sql, DBMS_SQL.NATIVE); v_RstExec := DBMS_SQL.EXECUTE(v_CursorID); LOOP IF DBMS_SQL.FETCH_ROWS(v_CursorID) = 0 THEN EXIT; END IF; DBMS_SQL.COLUMN_VALUE(v_CursorID, 1, v_val); DBMS_OUTPUT.PUT_LINE(v_val); END LOOP; DBMS_SQL.CLOSE_CURSOR(v_CursorID); end; /

  • PRO*Cでテーブル名にバインド変数は使えますか?

    PRO*Cのプログラムで、テーブル名とカラム名をパラメータで 受け取って、ホスト変数(バインド変数?)に代入して、 それぞれ、SELECT文等で使用できますか? PL/SQLなら出来るでしょうか? EXEC SQL BEGIN DECLARE SECTION; varchar t_name[64]; /* テーブル名 */ varchar col_name[64]; /* カラム名 */ EXEC SQL END DECLARE SECTION; /* 中略 パラメータの値をホスト変数に代入する処理を行う */ ↓以下のように出来ますか? SELECT :col_name FROM :t_name ;

  • バインド変数について

    PL/SQLのバインド変数について調べていますが理解できず困っています。 [理解内容] 1.利点  :SQL文の検索にバインド変数を利用すると、同一のSQLとして実行できる   ⇒ 繰り返し処理(ループ)では有効 2.使用方法  :静的SQL・動的SQLで使用可能   [疑問点]   静的SQLではバインド変数をどう宣言すればよいですか?   [SQL*Plus]・[動的SQL]は例文がありました   ●SQL*Plusでの宣言方法    (例)     SQL> set null '<null>'     SQL> set head off     SQL> variable var_at_sqlplus number   ●動的SQLの記述方法    (例)     declare      v_sql varchar2(256);      v_id varchar2(3);     begin      v_sql = 'select id into :v_id from test';      execute immediate v_sql into v_id;     end;   ●静的SQL ・・・【 エラーになる 】     declare      variable v_id varchar2(3);     begin      select id into :v_id from test'     end; どんな事でもかまいませんので回答よろしくお願いします

  • PL/SQLでテーブル名に変数を使いたい

    下記のようにV_TABLE_NAMEに不定のテーブル名で使用したい ご存知の方は教えて頂けないでしょうか?V_TABLE_NAMEに取得したテーブルをセットし、データの件数を取得するPL/SQL CURSOR C_CUR IS SELECT COUNT (*) FROM V_TABLE_NAME; BEGIN for ・・・・・ loop ・・・  ・・・ V_TABLE_NAME := GET_TABLE;  OPEN C_CUR;  FETCH C_CUR into w_count; CLOSE C_CUR; end loop;

  • TIMESTAMP型が含まれるテーブルの列名の取得

    Oracle 11gを使用しているSQL初心者です。 テーブルの列名を取得する方法についての質問です。 テーブルの列名を取得するときは以下のSQLで取れると思っています。 select column_name from user_tab_columns where table_name = 'テーブル名'; --実行結果-- COLUMN_NAME ------------------------------ NAME1 NAME2 しかし、テーブルにTIMESTAMP型が含まれていると 「レコードが選択されませんでした。」 と表示されます。 TIMESTAMP型が含まれるテーブルは上記のSQLでは取得できないのでしょうか。 TIMESTAMP型が含まれるテーブルの列名の取得方法をご存知の方がいらっしゃいましたら、 ご教示ください。よろしくお願い致します。

  • PL/SQLの動的SQLで複数の項目を取得する方法教えて下さい。

    動的SQLで複数の項目を取得する方法で 悩んでいます。 下記の例だと、1項目しか取れません。 何か他のやり方でもいいので、複数の項目を 取得する方法を教えていただきたいです。 ********************************************* declare sql_stmt varchar2(200); wk_grp varchar2(5); wk_name varchar2(30); type cursor_type is ref cursor; cur_name cursor_type; begin wk_grp := '1u'; open cur_name for 'select 名前 from 社員表 where 所属グループ = :v1' using wk_grp; loop fetch cur_name into wk_name; exit when cur_name%notfound; dbms_output.put_line(wk_name); end loop; close cur_name; end; ********************************************* 下記のようなDBMS_SQLパッケージ?? を利用した方法がいいんでしょうかね。。。。 DBMS_SQL.COLUMN_VALUE(SQL,1,WK_NAME) DBMS_SQL.COLUMN_VALUE(SQL,2,WK_NO) よくわかってないので、宜しくお願いします。

  • カーソルでLONG型のカラムが更新されない

    お世話になります。 LONG型のカラムに長い文字列がセットされてるのですが、その文字列の中からある特定の文字列を別の文字に置換したいのです。 SELECT ~ REPLACEを使おうと思ったのですが、LONG型では使えないらしく、PLSQLにて以下のように作成しました。 DECLARE CURSOR CURSOR1 IS SELECT * FROM T_テーブル; HIGH_VALUE_WORK VARCHAR2(32760); BEGIN FOR REC_CURSOR1 IN CURSOR1 LOOP HIGH_VALUE_WORK := REC_CURSOR1.カラム; HIGH_VALUE_WORK := REPLACE(HIGH_VALUE_WORK, 'あああ', '   '); REC_CURSOR1.カラム := HIGH_VALUE_WORK; END LOOP; END; / しかしテーブルを確認しても変更されてませんでした。 更新直後に試しにセレクトかけてDBMS_OUTPUTすると正しく更新されてました。 Oracleは10gR2です。 ご存知の方どうかよろしくお願いします。

  • 変数に入った値を変数として扱うことはできますか?

    VBスクリプトで自動で作成した値を変数に変化したいのですが、可能なのでしょうか? 例えば hensu = "5" ~DBのテーブルからフィールド名"hensu"を抜き出し、変数"field_set"に入れる。~ OpenField = OpenField & field_set& "=""&"& field_set&"&""" sql = "update test_table set" sql = sql &" "& OpenField sql = sql & "where scode = '" & scode & "'" という感じにしたいのですが、当然"field_set"には"5"ではなく"hensu"というフィールド名の文字列が入ります そもそも変数に入れた値を変数に変換する事って可能なのでしょうか? 宜しくお願い致します。

  • ストアド内でカラム名一覧を取得

    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ストアド内でカラム名一覧を取得、カンマで繋げてひとつの変数にまとめたい。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 現在開発でストアドを使用する機会があり、そこで不明点が発生し悩んでおります。 以下、現状と質問です。 ■SQL SERVER 2000 ■テーブル(※)のカラム名一覧を取得し、  カラム名をカンマで繋げてひとつの変数に格納したいと思っています。  ※先の処理でカラムを取得したいテーブルをSELECTしており、  対象のテーブル名を変数に代入しています。  カラム一覧を取得するにあたり、以下のようにカーソルで習得し、  FETCHでカラム名を変数に格納しようと考えていましたが、  「'対象テーブル名'」には変数がいれられないので、どうしようかと悩んでいます。  DECLARE CURS_test CURSOR FOR   SELECT name FROM dbo.syscolumns   WHERE id IN   (SELECT id FROM dbo.sysobjects WHERE name = '対象テーブル名')   ORDER BY id, colid;  「sp_executesql」を使用してselect文を流そうとしたのですが、  複数ある列名を取得して、上記で記載しましたように  カラム名をカンマで繋げてひとつの変数に格納する方法がわかりませんでした。  こういった場合、どのように考えて、どのように書けばよいのでしょうか。  まだ触り始めたばかりで、わからないことがわかっていない部分もあり、  質問内容でわかりにくい部分がありましたらご指摘いただければと思います。  どうぞよろしくお願いいたします。

  • 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 /