web-dev-qa-db-ja.com

pl / sqlストアド・プロシージャ:パラメータ名は列名と同じです

このようなストアドプロシージャがあります

procedure P_IssueUpdate
(
    Id in integer,
    ModifiedDate in date,
    Solution in varchar2
) AS
BEGIN
update T_Issue
Set
  ModifiedDate = ModifiedDate,
  Solution = Solution
where id = id;
END P_IssueUpdate;

私の問題は、パラメータ名がテーブルの列名と同じ名前であるということです。 「=」の後の値が列ではなくパラメータであることをSQLに指示する方法はありますか?

ご協力いただきありがとうございます

25
gsharp

次のように、パラメータ名と変数名の前にプロシージャの名前を付けることができます。

SQL> declare
  2     procedure p (empno number) is
  3        ename varchar2(10);
  4     begin
  5        select ename
  6        into p.ename
  7        from emp
  8        where empno = p.empno;
  9        dbms_output.put_line(p.ename);
 10     end;
 11  begin
 12     p (7839);
 13  end;
 14  /
KING

PL/SQL procedure successfully completed.
44
Tony Andrews

あなたが説明したものは 可変シャドウイング と呼ばれます。それはどの言語でも起こり得ます。良い回避策が与えられましたが、一般的な解決策は、それが決して起こらないように命名スキームを設計することです。

たとえば、プレフィックスなしで列に名前を付け、スコープに依存するプレフィックス付きの変数を設定します(P_パラメータの場合、L_ローカル変数の場合、G_グローバルパッケージ変数などの場合...)。これには、追加情報を提供することでコードを読みやすくするという追加の利点があります。

6
Vincent Malgrat

私は解決策を見つけました。パラメータを完全に修飾することで機能しています。

procedure P_IssueUpdate
(
    Id in integer,
    ModifiedDate in date,
    Solution in varchar2
) AS
BEGIN
update T_Issue
Set
  ModifiedDate = P_IssueUpdate.ModifiedDate,
  Solution = P_IssueUpdate.Solution
where id = P_IssueUpdate.id;
END P_IssueUpdate;
5
gsharp

プレフィックスの付加に関するREVincentの回答-このソリューションは、誰かがテーブルを変更し、名前がパラメーター名と衝突する列を追加するまで機能します。テーブルの変更が変数名またはパラメーター名と競合しないことを確認するために、すべての人がコードのすべての行を通過するわけではありません。 Oracleの推奨事項は、SQLクエリのすべてのパラメータまたは変数名を修飾することです。

(プロシージャの外で)匿名ブロックを使用している場合は、ブロックに名前を付けて、次のように変数を修飾できます。

<<MY_BLOCK>>
declare
   X   sys.USER_TABLES%rowtype;
   Y   sys.USER_TABLES.TABLE_NAME%type := 'some_table_name';
begin
   select UT.*
   into   MY_BLOCK.X
   from   sys.USER_TABLES UT
   where  UT.TABLE_NAME = MY_BLOCK.Y;
end MY_BLOCK;
3
Jim