하나의 데이터베이스에서 AQ 전파에 대한 작업을하고 있습니다. 그러나 전파를 예약하고 LOCAL AQ 테이블에 첫 번째 메시지를 대기열에 추가하면 DBA_QUEUE_SCHEDULES.LAST_ERROR_MSG에서 오류가 발생했습니다. "ORA-25215 : user_data 유형과 대기열 유형이 일치하지 않습니다." , 내가 같은 스크립트를 사용하여 만든 이름 만 변경 한,Oracle AQ 전파, ORA-25215 : user_data 유형 및 대기열 유형이 일치하지 않습니다.
create or replace type LOCAL_OBJ_MSG as object(
test varchar2(4000))
/
및 AQ 테이블 모두는 동일하다 : AQ 테이블에 사용 된 두 개체 유형 테스트 목적으로, 동일 내가이 일을 사용하고 있습니다 하나의 로컬 다른 원격. LOCAL AQ 테이블은 LOCAL 데이터베이스에 있으며, REMOTE 테이블은 SCHEMA_NAME.REMOTE 데이터베이스에 있습니다.
begin
-- Add the remote subscriber.
dbms_aqadm.add_subscriber(queue_name => 'LOCAL_oTEST',
subscriber => sys.aq$_agent(name => 'LOCAL_oTEST_subscriber',
address => '[email protected]_LINK_NAME',
protocol => 0),
queue_to_queue => true);
-- Start the propagation of messages.
dbms_aqadm.schedule_propagation(queue_name => 'LOCAL_oTEST',
latency => 0,
destination => 'DB_LINK_NAME',
destination_queue => 'SCHEMA_NAME.REMOTE_oTEST');
end;
/
: 스크립트 가입자, 디큐 절차 등 :
LOCAL DB를 생성하는 데 사용 여기
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24010);
begin
dbms_aqadm.stop_queue(
queue_name => 'REMOTE_iTEST');
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24010);
begin
dbms_aqadm.drop_queue('REMOTE_iTEST');
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24002);
begin
dbms_aqadm.drop_queue_table('REMOTE_iTEST', force => true);
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24010);
begin
dbms_aqadm.stop_queue(
queue_name => 'REMOTE_oTEST');
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24010);
begin
dbms_aqadm.drop_queue('REMOTE_oTEST');
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
QUEUE_NOT_FOUND exception;
PRAGMA EXCEPTION_INIT(QUEUE_NOT_FOUND, -24002);
begin
dbms_aqadm.drop_queue_table('REMOTE_oTEST', force => true);
exception
when QUEUE_NOT_FOUND then
null;
when others then
raise;
end;
/
declare
l_exist number;
cursor c_index is
select 1 from user_objects u where u.OBJECT_NAME = upper('LOCAL_OBJ_MSG') and u.OBJECT_TYPE = 'TYPE';
begin
open c_index;
fetch c_index into l_exist;
close c_index;
if l_exist = 1 then
execute immediate 'drop type LOCAL_OBJ_MSG';
end if;
end;
/
create or replace type LOCAL_OBJ_MSG as object(
test varchar2(4000))
/
begin
dbms_aqadm.create_queue_table (
queue_table => 'REMOTE_iTEST',
queue_payload_type => 'LOCAL_OBJ_MSG',
storage_clause => 'pctfree 5 pctused 90 tablespace SEPA_INTEG_AQ',
message_grouping => DBMS_AQADM.NONE,
sort_list => 'ENQ_TIME',
multiple_consumers => true,
comment => 'Incoming TEST message table.');
end;
/
begin
dbms_aqadm.create_queue (
queue_table => 'REMOTE_iTEST',
queue_name => 'REMOTE_iTEST',
queue_type => sys.dbms_aqadm.normal_queue,
retention_time => sys.dbms_aqadm.INFINITE,
comment => 'Incoming TEST messages.',
max_retries => 5);
end;
/
begin
dbms_aqadm.start_queue(
queue_name => 'REMOTE_iTEST',
dequeue => true,
enqueue => true);
end;
/
begin
dbms_aqadm.create_queue_table (
queue_table => 'REMOTE_oTEST',
queue_payload_type => 'LOCAL_OBJ_MSG',
storage_clause => 'pctfree 5 pctused 90 tablespace SEPA_INTEG_AQ',
message_grouping => DBMS_AQADM.NONE,
sort_list => 'ENQ_TIME',
multiple_consumers => true,
comment => 'Outgoing TEST message table.');
end;
/
begin
dbms_aqadm.create_queue (
queue_table => 'REMOTE_oTEST',
queue_name => 'REMOTE_oTEST',
queue_type => sys.dbms_aqadm.normal_queue,
retention_time => sys.dbms_aqadm.INFINITE,
comment => 'Outgoing TEST messages.',
max_retries => 5);
end;
/
begin
dbms_aqadm.start_queue(
queue_name => 'REMOTE_oTEST',
dequeue => TRUE,
enqueue => TRUE);
end;
/
을 그리고 다음은
내가 AQ 테이블을 만드는 데 사용했습니다 스크립트입니다 원격 데이터베이스 :-- Create a table to store the messages received.
create table sepa_omsg_aq_demo
(received timestamp default systimestamp,
message LOCAL_OBJ_MSG);
-- Create a callback procedure that dequeues the received message and saves it
create or replace
procedure REMOTE_CALLBACK_TEST
(
context raw,
reginfo sys.aq$_reg_info,
descr sys.aq$_descriptor,
payload raw,
payloadl number
)
as
r_dequeue_options dbms_aq.dequeue_options_t;
r_message_properties dbms_aq.message_properties_t;
v_message_handle raw(26);
o_payload LOCAL_OBJ_MSG;
begin
r_dequeue_options.msgid := descr.msg_id;
r_dequeue_options.consumer_name := descr.consumer_name;
dbms_aq.dequeue(queue_name => descr.queue_name,
dequeue_options => r_dequeue_options,
message_properties => r_message_properties,
payload => o_payload,
msgid => v_message_handle);
insert into sepa_omsg_aq_demo
(message)
values (o_payload);
commit;
exception
when others then
rollback;
end;
/
-- Register the procedure for dequeuing the messages received.
-- I'd like to point out that the subscriber is the one defined for the local database
begin
dbms_aq.register (
sys.aq$_reg_info_list(
sys.aq$_reg_info('REMOTE_oTEST:LOCAL_oTEST_subscriber',
dbms_aq.namespace_aq,
'plsql://REMOTE_CALLBACK_TEST',
hextoraw('FF'))
),
1);
end;
/
declare
enq_msgid raw(16);
eopt dbms_aq.enqueue_options_t;
mprop dbms_aq.message_properties_t;
message local_obj_msg;
begin
message := local_obj_msg('a');
dbms_aq.enqueue(queue_name => 'LOCAL_oTEST',
enqueue_options => eopt,
message_properties => mprop,
payload => message,
msgid => enq_msgid);
commit;
end;
/
은 또한 SYS.AQ $ _MESSAGE_TYPES 테이블 (LOCAL DB), 생성 된 전파 확인 상태 = 'F'에서 점에 유의하고, :
Sript은 LOCAL AQ 테이블에 메시지를 대기열하기
declare
rc binary_integer;
begin
dbms_aqadm.verify_queue_types(src_queue_name => 'local_otest',
dest_queue_name => 'schema_name.remote_otest',
rc => rc,
destination => 'db_link_name');
dbms_output.put_line('Compatible: ' || rc);
end;
/
은 0을 반환합니다. 이는 테이블 유형이 호환되지 않음을 의미합니다. 내가 로컬 파견과 NLS_LENGTH_SEMANTICS의 원격 데이터베이스가 다르다면, 원격 파급이 불가능하다는 것을 발견했다. 그러나이 상황에서는 그렇지 않다. 나는 확인했다. 어떤 생각이 내가 뭘 잘못하고 있는지 또는 어떻게이 두 테이블간에 차이점을 발견하고이를 고칠 수 있습니까? 또는 그것은 아마도 일부 DB 매개 변수 값 사이의 차이 일 수 있습니까?
오라클 데이터베이스는 확인 11.2.0.3.0
답해 주셔서 감사합니다. 그러나 두 데이터베이스 모두에서 NLS_LENGTH_SEMANTICS는 CHAR로 설정됩니다. –
2 개의 Oracle 11.2.0.3.0에서 제공 한 스크립트를 성공적으로 실행했습니다. 메시지를 Enqueing하면 문제없이 잘 작동하며 메시지는 원격 대기열로 전달됩니다. 나는 그것이 명백하게 들릴지도 모르지만 NLS 주제를 방문한다는 것을 알고 있습니다. 귀하의 dbs에 대해 이것이 동일하다는 것을 확인할 수 있습니까? 'select * from nls_database_parameters 여기서, parameter = 'NLS_LENGTH_SEMANTICS'; select * from nls_instance_parameters 여기서 매개 변수 = 'NLS_LENGTH_SEMANTICS'; select * from nls_session_parameters 여기서 parameter = 'NLS_LENGTH_SEMANTICS'; ' –
예, 이들은 다릅니다. 리모컨에서 CHAR, CHAR, CHAR, LOCAL, BYTE, CHAR, CHAR가 있습니다. 이전에 v $ 매개 변수를 체크인했는데이 뷰에 대해서는 알지 못했습니다. 그래서 지금은 내 원격 객체를 다시 만들 필요가 ... varchar2 (4000 CHAR)) ...? –