
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;
どんな事でもかまいませんので回答よろしくお願いします
No.2ベストアンサー
- 回答日時:
#1 です。
>という事はPL/SQL内の静的SQLではバインド変数は使えないと言うことでしょうか?
ストアドプログラム(パッケージ/プロシージャ/ファンクション)内では動的以外には使えないと思います。
(SQL*PlusからストアドをEXECUTEする時の引数として使用する事は、もちろん可能ですが)
但し、私が例に書いた通り、無名PL/SQLブロック(DECLARE~BEGIN~END)内では静的にも使用可能です。
質問者様の試したサンプルで言えば。
CREATE OR REPLACE PROCEDURE TEST.TEST(v_Id IN VARCHAR2) IS
v_name varchar2(20);
BEGIN
SELECT name
INTO v_name
FROM test
WHERE id = v_Id;
EXCEPTION
WHEN OTHERS THEN
RETURN;
END;
/
これでコンパイルは通りますよね。(すいません、環境が無いので未検証です)
「これじゃ、v_Idはバインド変数にならないんじゃ?」と思うかもしれませんが、これバインド変数なんです。
(うーん、混乱しちゃいますかね?)
SQLトレースを取るとわかるんですが、引数v_Idが '1' だろうが '2' だろうがトレースで解析されるSQLでは
WHERE id = :b1
と言うバインド変数になるんですよ。
>このあたりが理解できていない部分です。
パフォーマンスチューニングで扱われるバインド変数と置換変数(リテラル)の差異を把握する事が、実はこの辺の理屈を理解する上での近道かもしれません。
OTNでパフォーマンス・チューニング・ガイドを落とすか、もしくはパフォチュー系の本を一冊読んでみるとよいかと思います。
もしJavaの経験がおありでしたら、"?"(プレースホルダ)を使ったSQLと、リテラル直指定の同じSQLをそれぞれ実行するJDBCプログラムを作って、SQLトレース(とtkprof)を取って較べてみると見えてくる物があると思います。
私自身、SQLトレースの中身を見るようになって、この辺の事が理解できるようになりましたから。
(SQLトレースに関しては前述のチューニング・ガイド等参照)
No.1
- 回答日時:
variable はSQL*Plusのコマンドなのでdeclareの後(無名PL/SQLブロック内)に記述する事はできません。
ブロックの外で記述してください。
他に変数が無いならdeclareも不要です。BEGIN~ENDだけでOKです。
質問者様の例だとシンタックスエラーになりますが、記載ミスと思われるので修正しました。
(testの後のクォートは余分、セミコロンが無い)
variable v_id varchar2(3);
begin
select id into :v_id from test;
end;
/
回答・訂正ありがとうございます。
という事はPL/SQL内の静的SQLではバインド変数は使えないと言うことでしょうか?
以下が今回試してみた全文です。
----------------------------------------------------------------
CREATE OR REPLACE PROCEDURE TEST.TEST(v_Id IN VARCHAR2) IS
v_name varchar2(20);
BEGIN
SELECT name
INTO v_name
FROM test
WHERE id = :v_Id;
EXCEPTION
WHEN OTHERS THEN
RETURN;
END;
----------------------------------------------------------------
この場合以下のエラーになりました。
>PLS-00049:bad bind variable 'V_ID'
このあたりが理解できていない部分です。
バインド変数を使用するにあたり、基本的な事かもしれませんがよろしくお願いします
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- MySQL テーブル作成です。どこかのスペルが間違っているか記号など スペースかな? 1 2022/10/01 05:08
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- MySQL #1062 - '0' は索引 'PRIMARY' で重複しています。とでています。 1 2023/01/01 06:13
- Visual Basic(VBA) ActiveReportのdetailをデータセットの自動バインドを使って帳票を出力しています。 1 2023/08/16 07:16
- IT・エンジニアリング ActiveReportのdetailをデータセットの自動バインドを使って帳票を出力しています。 1 2023/08/16 07:17
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- Visual Basic(VBA) データベースから絞り込んでデータを読み込み 1 2023/02/21 19:51
このQ&Aを見た人はこんなQ&Aも見ています
-
PL/SQL PLS-00103エラーについて
Oracle
-
Statement ignored というエラー
Oracle
-
SELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?
PostgreSQL
-
-
4
PL/SQLのコンパイルエラーについて(ignored)
Oracle
-
5
PL/SQLでのSQL文法
その他(データベース)
-
6
PL/SQLカーソルの2重FORループができません
Oracle
-
7
ストアドプロシジャからストアドプロシジャを呼ぶには?
Oracle
-
8
CASE文のエラーについて
Oracle
-
9
PL/SQLの変数について
Oracle
-
10
テーブルからのselectにおいてデータの有無により結果をわけたい
PostgreSQL
-
11
変数が選択リストにありません
Oracle
-
12
カーソル0件の時にエラーを発生させる
Oracle
-
13
ORA-01013のエラーについて経験のある方お願いします。
Oracle
-
14
不明なコマンドです(FROM")。行の残りは無視されました。 のエラー"
Oracle
-
15
PLSQLの識別子エラー
Oracle
-
16
SQLローダーCSV取込で、囲み文字がデータ中に入っている場合について
Oracle
-
17
エラーを起こす方法
Oracle
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
selectした大量データをinsert...
-
select文のwhere句に配列を入れ...
-
SQL Left Join で重複を排除す...
-
ある条件の最大値+1を初番する...
-
[MySQL] 3つのテーブルの結合で...
-
updateを1行ずつ実行したい。
-
エラー 1068 (42000): 複数の主...
-
マイクラPC版のコマンドで効率...
-
WordpressのContact form 7でzi...
-
Postgreのupdateコマンドでエラー
-
ポニョの替え歌のポーニョポニ...
-
複数テーブルのGROUP BY の使い...
-
テーブルのフィールド名の命名...
-
連動させて表示させる方法
-
sqlで、600行あるテーブルを100...
-
【Transact-sql】 execの結果を...
-
【初心者】特定の文字に色をつ...
-
MYSQLのクエリの最適化について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
sqlで、600行あるテーブルを100...
-
select文のwhere句に配列を入れ...
-
SQLにて特定の文字を除いた検索...
-
WordpressのContact form 7でzi...
-
SQLサーバから、項目の属性(型...
-
VIEWの元のテーブルのindexって...
-
クエリ表示と、ADOで抽出したレ...
-
マイクラPC版のコマンドで効率...
-
【Transact-sql】 execの結果を...
-
SQL Left Join で重複を排除す...
-
エラー 1068 (42000): 複数の主...
-
[MySQL] UNIQUE制約の値を更新...
-
inner joinをすると数がおかし...
-
1テーブル&複数レコードの更新...
-
Access パラメータクエリをcsv...
-
期間の重複を調べるSQL文につい...
-
Unionした最後にGROUP BYを追加...
-
Updateの複数テーブル条件時のL...
おすすめ情報