0

我在事务中插入一条记录,然后我通过 Oracle 函数检索相同的记录。oracle 函数不返回任何记录。我的 DBA 告诉我,Oracle 函数不在事务中运行。我该如何解决这个问题?

示例:使用 oracle 提供程序开始事务

执行一些 SQL:

插入所有者(FIRST_NAME,LAST_NAME)值('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

The AUTONOMOUS_TRANSACTION pragma means that the function operates in the context of a separate transaction. By default (see http://docs.oracle.com/cd/B19306_01/server.102/b14220/consist.htm#sthref1972) this uses the "read committed" isolation level, meaning that, when the transaction queries data, it sees only data that was committed before the query began. Since the data you inserted has not been committed, this means that the function can't see it.

于 2012-09-20T17:25:27.057 回答
1

来自 Oracle 文档:

AUTONOMOUS_TRANSACTIONpragma 改变了子程序在事务中的工作方式。标有此 pragma 的子程序可以执行 SQL 操作并提交或回滚这些操作,而无需提交或回滚主事务中的数据。

你能试着摆脱那个杂注吗?

最后,“我的 DBA 告诉我 Oracle 函数不在事务中运行”是有问题的。我不是专家,但我真诚地怀疑这是否正确。

于 2012-09-20T17:05:44.707 回答