0

トランザクション内にレコードを挿入し、後でOracle関数を介して同じレコードを取得しています。oracle関数はレコードを返していません。私のDBAは、Oracle関数はトランザクション内では動作しないと言っていました。これを回避するにはどうすればよいですか?

例:Oracleプロバイダーを使用してトランザクションを開始します

SQLを実行します。

INSERT OWNER(FIRST_NAME、LAST_NAME)VALUES('JOHN'、'SMITH')

関数からトランザクション内のレコードを取得します(71はIDの例です):select * from table(GET_OWNER_DETAILS_FNC(71))

Oracle関数は次のとおりです。

CREATE OR REPLACE FUNCTION "AROH"."GET_OWNER_DETAILS_FNC" (p_owner_information_oid  in aroh_owner_information.owner_information_oid%type ) 
return OWNER_DETAILS_TABLE_TYPE_FNC

IS 
PRAGMA AUTONOMOUS_TRANSACTION; 

v_owner_details_set   OWNER_DETAILS_TABLE_TYPE_FNC := OWNER_DETAILS_TABLE_TYPE_FNC();

CURSOR c_owner_dtls IS
select oi.owner_information_oid, 
oi.first_name, 
oi.last_name, 
oi.company_name, 
oi.license_information, 
oi.company_ind, 
oi.middle_initial, 
oi.title_type_oid, 
oi.suffix, 
oi.status_type_code, 
oi.primary_phone, 
oi.secondary_phone, 
oi.secondary_phone_type_code, 
oi.primary_phone_type_code, 
oi.email_address, 
oi.comments, 
oi.primary_phone_extension, 
oi.secondary_phone_extension, 
poa.owner_address_oid as primaryaddressid, 
poa.address_type_code as primaryaddresscode, 
poa.address1 as primaryaddress1, 
poa.address2 as primaryaddress2, 
poa.city as primarycity, 
poa.state as primarystate, 
poa.postal_code as primaryzip, 
poa.current_ind as primarycurrent, 
soa.owner_address_oid as secondaryaddressid,
soa.address_type_code as secondaryaddresscode, 
soa.address1 as secondaryaddress1, 
soa.address2 as secondaryaddress2, 
soa.city as secondarycity, 
soa.state as secondarystate, 
soa.postal_code as secondaryzip, 
soa.current_ind as secondarycurrent,
(    select
      (    select oa2.owner_information_oid 
            from aroh_owner_aircraft_rlshp oa2 
            where upper(primary_owner) like '%PRIMARY%' 
                            and oa2.aircraft_oid = oa1.aircraft_oid
                            and rownum = 1) as prim_owner_oid
                from aroh_owner_aircraft_rlshp oa1
                where oa1.owner_information_oid = p_owner_information_oid
                   and rownum = 1 
) as primary_owner_oid,
(          select 
              case when (upper(primary_owner) like '%PRIMARY%')
                                                then 'Y'
                                                else 'N' end as isprimary
                from aroh_owner_aircraft_rlshp
                where owner_information_oid = p_owner_information_oid
                and rownum = 1
) as is_primary
from aroh_owner_information oi 
inner join (select * 
                  from aroh_owner_address 
                where upper(current_ind) = 'Y' 
                    and address_type_code = 'OPRIM') poa 
on oi.owner_information_oid = poa.owner_information_oid 
left outer join (select * 
                        from aroh_owner_address 
                        where upper(current_ind) = 'Y' 
                        and address_type_code = 'OSEC') soa 
on oi.owner_information_oid = soa.owner_information_oid 
where   oi.owner_information_oid = p_owner_information_oid; 

begin 

For main_row in c_owner_dtls 
loop 
  v_owner_details_set.EXTEND; 
  v_owner_details_set(v_owner_details_set.LAST) :=  OWNER_DETAILS_TYPE    (main_row.owner_information_oid  , main_row.first_name   , main_row.last_name   , main_row.company_name   
   , main_row.license_information   , main_row.company_ind   , main_row.middle_initial   , main_row.title_type_oid   , main_row.suffix    , main_row.status_type_code   , main_row.primary_phone  
   , main_row.secondary_phone   , main_row.secondary_phone_type_code   , main_row.primary_phone_type_code   , main_row.email_address   , main_row.comments   , main_row.primary_phone_extension   
   , main_row.secondary_phone_extension   , main_row.primaryaddressid   , main_row.primaryaddresscode   , main_row.primaryaddress1   , main_row.primaryaddress2   , main_row.primarycity   
   , main_row.primarystate   , main_row.primaryzip   , main_row.primarycurrent   , main_row.secondaryaddressid    , main_row.secondaryaddresscode   , main_row.secondaryaddress1   
   , main_row.secondaryaddress2   , main_row.secondarycity   , main_row.secondarystate   , main_row.secondaryzip    , main_row.secondarycurrent   , main_row.primary_owner_oid   , main_row.is_primary ); 
end loop; 

return v_owner_details_set;

EXCEPTION
When others 
then dbms_output.put_line ('Oracle error: '||SQLERRM);

end;
4

2 に答える 2

3

AUTONOMOUS_TRANSACTIONプラグマは、関数が別のトランザクションのコンテキストで動作することを意味します。デフォルトでは ( http://docs.oracle.com/cd/B19306_01/server.102/b14220/consist.htm#sthref1972を参照)、これは「コミットされた読取り」分離レベルを使用します。つまり、トランザクションがデータを問い合せると、クエリが開始される前にコミットされたデータのみが表示されます。挿入したデータはコミットされていないため、関数がそれを認識できないことを意味します。

于 2012-09-20T17:25:27.057 に答える
1

オラクルのドキュメントから:

AUTONOMOUS_TRANSACTIONプラグマは、サブプログラムがトランザクション内で動作する方法を変更します。このプラグマでマークされたサブプログラムは、メイン トランザクションでデータをコミットまたはロールバックすることなく、SQL 操作を実行し、それらの操作をコミットまたはロールバックできます。

そのプラグマを削除してみてください。

最後に、「私の DBA は、Oracle 関数はトランザクション内で動作しないと私に言いました」は疑問です。私は専門家ではありませんが、これが正しいかどうかは疑問です。

于 2012-09-20T17:05:44.707 に答える