このようなストアドプロシージャがあります
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に指示する方法はありますか?
ご協力いただきありがとうございます
次のように、パラメータ名と変数名の前にプロシージャの名前を付けることができます。
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.
あなたが説明したものは 可変シャドウイング と呼ばれます。それはどの言語でも起こり得ます。良い回避策が与えられましたが、一般的な解決策は、それが決して起こらないように命名スキームを設計することです。
たとえば、プレフィックスなしで列に名前を付け、スコープに依存するプレフィックス付きの変数を設定します(P_
パラメータの場合、L_
ローカル変数の場合、G_
グローバルパッケージ変数などの場合...)。これには、追加情報を提供することでコードを読みやすくするという追加の利点があります。
私は解決策を見つけました。パラメータを完全に修飾することで機能しています。
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;
プレフィックスの付加に関する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;