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も見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
CASE文のエラーについて
Oracle
-
PL/SQL PLS-00103エラーについて
Oracle
-
Statement ignored というエラー
Oracle
-
-
4
【PL/SQL】FROM区に変数を使う方法
Oracle
-
5
変数が選択リストにありません
Oracle
-
6
PL/SQLでログを確認したい。
Oracle
-
7
PLSQLのバインド変数の件です。
Oracle
-
8
PL/SQLをWindowsのBATファイルで実行するには
Oracle
-
9
select句副問い合わせ 値の個数が多すぎます
Oracle
-
10
PL/SQLのコンパイルエラーについて(ignored)
Oracle
-
11
PL/SQLカーソルの2重FORループができません
Oracle
-
12
Viewにインデックスは張れますか?
Oracle
-
13
不明なコマンドです(FROM")。行の残りは無視されました。 のエラー"
Oracle
-
14
SELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?
PostgreSQL
-
15
PLSQLの識別子エラー
Oracle
-
16
エラーを起こす方法
Oracle
-
17
PL/SQLでPLS-00201のエラー
Oracle
-
18
GROUP BYを行った後に結合したい。
Oracle
-
19
ストアド・プロシージャをバッチから起動させて実行する方法
Oracle
-
20
SELECT文の結果をDEFINEの値として使用したいのですが。。。 [Oracle9i]
Oracle
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
上位3位を求めるSQL文は?
-
副問合せの書き方について
-
Access パラメータクエリをcsv...
-
VIEWの元のテーブルのindexって...
-
ある時間以内の利用者の抽出に...
-
insertを高速化させたい
-
SQL Left Join で重複を排除す...
-
ある条件の最大値+1を初番する...
-
1テーブル&複数レコードの更新...
-
エクセルの関数について教えて...
-
全角文字を含む行を検索
-
同一のユーザー、同一商品のと...
-
テーブル作成です。どこかのス...
-
ストアドのエラーについて
-
クエリ表示と、ADOで抽出したレ...
-
[MySQL] 3つのテーブルの結合で...
-
入力値と外部キーをINSERTするには
-
親と子供が複数のSQL取得方法
-
select文のwhere句に配列を入れ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
副問合せの書き方について
-
SQLサーバから、項目の属性(型...
-
SQL Left Join で重複を排除す...
-
select文のwhere句に配列を入れ...
-
VIEWの元のテーブルのindexって...
-
PL/SQLの変数について
-
マイクラPC版のコマンドで効率...
-
エクセルの関数について教えて...
-
SQLにて特定の文字を除いた検索...
-
sqlで、600行あるテーブルを100...
-
Access パラメータクエリをcsv...
-
Unionした最後にGROUP BYを追加...
-
inner joinをすると数がおかし...
-
複数テーブルのGROUP BY の使い...
-
ある条件の最大値+1を初番する...
-
MySQLのint型で001と表示する方...
-
クエリ表示と、ADOで抽出したレ...
-
[MySQL] UNIQUE制約の値を更新...
-
テーブル名を省略して「h.id」...
おすすめ情報