#sql #oracle #dynamic #plsql #dblink
Вопрос:
У меня есть эта рабочая часть кода, это фрагмент большей рабочей функции. В текущей форме он работает в одном экземпляре «DBLINK», мне нужно изменить его на экземпляр динамического переключения, заменив dblink.
begin
pNDRZ := RW_DOK_SYSTEM.create_header@DBLINK( aNMGZ => NULL, aNKNT => pNKNT , aREZR => 'T' , aNTPD => pNTPD, aNODD => pNODD , aOPHP => pOPER);
B2B_P_LOG_ADD(pPAKC => 'B2B_P_DRZ_H_NEW', pERRO => SQLERRM, pTEXT => ' 2.1 Tworz naglowek - OK', pDAKT => SYSDATE, pDBLK => pDBLK, pNRZM => pNRZM, pNDRZ => pNDRZ, pPOZC => pPOZC, pNKNT => pNKNT, pNTWR => pNTWR, pILSP => pILSP, pCNSP => pCNSP, pCBSP => pCBSP, pNPRM => pNPRM, pUWAG => pUWAG, pSTAK => dbms_utility.format_call_stack );
exception
when others then
B2B_P_LOG_ADD(pPAKC => 'B2B_P_DRZ_H_NEW', pERRO => SQLERRM||' - '||SQLStatement2, pTEXT => wynik||' 2.1 Tworz naglowek - ERROR', pDAKT => SYSDATE, pDBLK => pDBLK, pNRZM => pNRZM, pNDRZ => pNDRZ, pPOZC => pPOZC, pNKNT => pNKNT, pNTWR => pNTWR, pILSP => pILSP, pCNSP => pCNSP, pCBSP => pCBSP, pNPRM => pNPRM, pUWAG => pUWAG, pSTAK => dbms_utility.format_call_stack );
return(0);
end;
Ключевая строка-это вот эта, остальное-массивный журнал и обработка ошибок:
pNDRZ := RW_DOK_SYSTEM.create_header@DBLINK( aNMGZ => NULL, aNKNT => pNKNT , aREZR => 'T' , aNTPD => pNTPD, aNODD => pNODD , aOPHP => pOPER);
pNDRZ-это идентификатор uniqe для документа. Мне нужно изменить этот код в динамическую форму, в которой я заменяю ссылку dblink при вызове функции.
Как функция динамического вызова, я могу сделать это с помощью процедуры, но я застрял на этом. Пожалуйста, помогите.
Ответ №1:
Вам понадобится динамический SQL (как вы и предполагали). Для этого
- создайте локальную переменную, которая будет использоваться для составления инструкции SQL (
l_str
в моем примере)- почему бы не использовать его напрямую? Поскольку динамический SQL трудно отлаживать, поэтому сначала отобразите его и — как только он будет хорошо работать — выполните его
- если опубликованный вами код является частью хранимой процедуры, вы, вероятно, передадите имя ссылки на базу данных в качестве параметра. Я создал локальную переменную для этой цели (
l_db_link
)
Я сократил те длинные команды, которые вы написали, нет смысла писать их все.
declare
l_str varchar2(200); -- used to compose a dynamic SQL statement
l_db_link varchar2(30) := 'ORCL';
pndrz number; -- just guessing; I don't know its datatype
begin
l_str := 'select rw_dok_system.create_header@' || l_db_link || '(anmgz => null) from dual';
execute immediate l_str into pndrz;
b2b_p_log_add(ppakc => 'B2B_P_DRZ_H_NEW');
exception
...
end;
Комментарии:
1. Спасибо, это почти работает, я получаю, что ora-14551 не может выполнить операцию DML внутри запроса. Этот запрос отображает одну строку в таблице документов. Я не могу использовать автономную транзакцию-это рискованно. Я решил использовать каскад операторов else-if. По одному на каждый возможный отдел. И да, я знаю, что это жесткое кодирование «катастрофы в процессе становления» 🙁 Но у меня ограниченное время. Я постараюсь сделать это лучше когда-нибудь в далеком будущем 😉 Спасибо!
2. Пожалуйста. Что касается ошибки, которую вы получили — ну, я не знал, что делает процедура (очевидно, DML). Я рад, что ты знаешь , что происходит и как это исправить.