私は%ROWTYPE
がここで行き詰まっていると思います。私が知る限り、PL/SQL変数に関する有用なメタデータを抽出する方法があります。
ただし、抽象データ型(ADTまたは "オブジェクト")を使用できる場合は、状況が異なります。それはより強力で、%ROWTYPE
と似ています。しかし、これはあまり便利ではなく、初期コードを少し複雑にします。オブジェクトをあらかじめ定義し、SQLで使用する必要があります。例えば
、このようなコードに置き換えます。これで
declare
v_test tbl%rowtype;
begin
select * into v_test from tbl;
end;
/
:
declare
v_test2 tbl_type;
begin
select tbl_type(msrp, some_other_column) into v_test2 from tbl;
end;
/
それが許容可能であるならば、あなたの更新のための動的PL/SQLを使用することができます。
--Create table, ADT, and test data
create table tbl(MSRP varchar2(100), some_other_column varchar2(100));
create or replace type tbl_type as object
(
msrp varchar2(100),
some_other_column varchar2(100)
);
/
insert into tbl values('1', '1');
--Convert object to ANYDATA, process with dynamic PL/SQL
declare
my_tbl tbl_type := tbl_type('2', '3');
procedure UpdateByColumn(p_anydata in anydata, colName in varchar2) is
v_typename varchar2(30) := p_anydata.getTypeName;
begin
execute immediate '
declare
v_anydata2 anydata := :anydata;
v_object '||v_typename||';
v_dummy pls_integer;
begin
v_dummy := v_anydata2.getObject(v_object);
update tbl set '||colName||' = v_object.'||colName||';
end;
' using p_anydata;
end;
begin
updateByColumn(anyData.convertObject(my_tbl), 'MSRP');
end;
/
--Show the new data
select * from tbl;
MSRP SOME_OTHER_COLUMN
---- -----------------
2 1
を
更新
%ROWTYPE
は、PL/SQLにのみ存在します。これらの値を渡す方法はありません。しかし、レコードをパッケージ変数として格納し、その変数の名前と型を関数に渡すことができます。この関数は、動的PL/SQLを使用してレコードを参照し、SQLで使用する値に変換できます。
(これは、一度に複数の列を変更する問題に対処しない、それが動的に%ROWTYPE
を使用する方法を示すだけのデモです。)
--Create table and test data
create table tbl(MSRP varchar2(100), some_other_column varchar2(100));
insert into tbl values('1', '1');
commit;
--Create another table, tbl2, that will be used to update tbl
--(The tables in this example have similar columns, but that is not
--actually necessary.)
create table tbl2(MSRP varchar2(100), some_other_column varchar2(100));
insert into tbl2 values('2', '2');
commit;
--New function works by passing in names of global variables and
--their types, instead of actual values.
create or replace procedure UpdateByColumn(
p_package_and_variable_name in varchar2,
p_rowtype in varchar2,
colName in varchar2) is
begin
execute immediate '
declare
v_rec '||p_rowtype||' := '||p_package_and_variable_name||';
begin
update tbl set '||colName||' = v_rec.'||colName||';
end;
';
end;
/
--A test package that calls the function to update tbl.
create or replace package test_package is
tbl2_rec tbl2%rowtype;
procedure test_procedure;
end;
/
create or replace package body test_package is
procedure test_procedure is
begin
select * into tbl2_rec from tbl2;
UpdateByColumn('test_package.tbl2_rec', 'tbl2%rowtype', 'MSRP');
end;
end;
/
begin
test_package.test_procedure;
end;
/
%の行型の記録ではないように思え使用するデータ型はわかりませんが、あなたが何をしようとしているのか、なぜそれを知っていなくてもわかりません。たぶん、控えめな配列が適しているでしょう。タイプは、のテーブルです。インデックスはvarchar2(30)です。 –
llayland
最終的にはそれも私が思いついたものです。行データ型からすべてのデータをANYDATAの連想配列に読み込み、配列を共通ルーチンに渡して、名前で列を参照できるようにすることになります。 – dreamfly