Страница 1 из 1
ORACLE PL/SQL
Добавлено: 27.03.2012 18:45
Гость
оракловский PLSQL отличается таким синтаксисом что читать я это могу а написать чего с нуля - большие трудности.
дано: табличка TABLE1.
колонки:
ID
SQL_STATEMENT
предполагается что в поле SQL_STATEMENT лежит правильный query (каждый query делает что то вроде INSERT... SELECT т.е. заполняет другую табличку)
задание 1
надо написать процедуру на PL SQL которая подряд запускает все TABLE1.SQL_STATEMENT
задание 2
предположим что у каждого SQL_STATEMENT есть 4 параметра (т.е. bind variables или как их там)
у процедуры такие же 4 параметра.
процедура запускает каждый TABLE1.SQL_STATEMENT с 4 параметрами
должно быть просто, но я в этом PLSQL как корова на льду.
а засовывать эти TABLE1.SQL_STATEMENT в код процедуры - плохая идея, их может быть штук 30 и меняться они будут часто.
это что то вроде маленького генератора отчетов
да, правильная обработка ошибок в PLSQL - это как? один из 30 запросов выдал ошибку. куда ее девать, как ее показывать?
Re: ORACLE PL/SQL
Добавлено: 27.03.2012 18:52
Гость
Почему бы не пользоваться хранимыми процедурами с параметрами, которые как раз хранить в записях БД?
Любая книжка Фойерштайна поможет тебе и с обработкой ошибок и с многими другими вещами.
Re: ORACLE PL/SQL
Добавлено: 27.03.2012 19:02
Джимми
EXECUTE IMMEDIATE -
http://docs.oracle.com/cd/B12037_01/app ... ems017.htm
цикл плскюель -
http://docs.oracle.com/cd/B28359_01/app ... m#CIHEJBAB
правильная обработка -
http://docs.oracle.com/cd/B13789_01/app ... 7_errs.htm" onclick="window.open(this.href);return false;
что с ошибкой делать тебе решать.
Ты тестовое задание где-то делаешь что-ли?
Re: ORACLE PL/SQL
Добавлено: 29.03.2012 11:13
JustMax
Надеюсь разберешься сам в рабочем примере.
Код: Выделить всё
CREATE OR REPLACE PROCEDURE PMSD.SP_POSTPROCESSING(v_Profile_Name VARCHAR2, v_Table_To_Export VARCHAR2) IS
v_Error VARCHAR2(250);
v_Execute VARCHAR2(1000);
BEGIN
FOR r_Postprocess_Procs IN (SELECT Procedure_Name FROM postprocess_procedure WHERE profile_name = v_Profile_Name ORDER BY invoke_order) LOOP
v_Execute := 'BEGIN '||r_Postprocess_Procs.Procedure_Name||'(:1); END;';
EXECUTE IMMEDIATE v_Execute USING v_Table_To_Export;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
v_Error := SUBSTR(SQLERRM,1,250);
INSERT INTO pmsd.protocol (action_date, name, descr) VALUES (SYSDATE, 'Error in export postprocessing', v_Error );
COMMIT;
RAISE;
END SP_POSTPROCESSING;
/
Вместо процедур можно также использовать текст SQL запросов с subtitute параметрами :1 :2 :3 и так далее, а потом подставлять их после USING
Re: ORACLE PL/SQL
Добавлено: 29.03.2012 11:55
Гость
JustMax писал(а):Надеюсь разберешься сам в рабочем примере.
Код: Выделить всё
CREATE OR REPLACE PROCEDURE PMSD.SP_POSTPROCESSING(v_Profile_Name VARCHAR2, v_Table_To_Export VARCHAR2) IS
v_Error VARCHAR2(250);
v_Execute VARCHAR2(1000);
BEGIN
FOR r_Postprocess_Procs IN (SELECT Procedure_Name FROM postprocess_procedure WHERE profile_name = v_Profile_Name ORDER BY invoke_order) LOOP
v_Execute := 'BEGIN '||r_Postprocess_Procs.Procedure_Name||'(:1); END;';
EXECUTE IMMEDIATE v_Execute USING v_Table_To_Export;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
v_Error := SUBSTR(SQLERRM,1,250);
INSERT INTO pmsd.protocol (action_date, name, descr) VALUES (SYSDATE, 'Error in export postprocessing', v_Error );
COMMIT;
RAISE;
END SP_POSTPROCESSING;
/
Вместо процедур можно также использовать текст SQL запросов с subtitute параметрами :1 :2 :3 и так далее, а потом подставлять их после USING
Спасибо!!! это точно оно!!!
тока один вопрос
WHEN OTHERS - это типа catch all такое?
а как сделать чтобы любые ошибки выдавались в stdout или лучше в stderr и цикл продолжался (я точно знаю что эта процедура будет запускаться из скрипта у которого есть stdout и stderr)?
ну т.е. нужен try - catch блок вокруг EXECUTE IMMEDIATE основные ошибки будут лезть оттуда
Re: ORACLE PL/SQL
Добавлено: 29.03.2012 13:59
The__Which
вот так делаешь "try catch" на каждую итерацию цикла:
Код: Выделить всё
begin
for ,,,, loop
begin
execute immediate ...
exception
when others...
обрабатываешь, z.B. пишешь сообщение об исключение об исключении куда тебе надо
end;
end loop;
end;
аналога stdout нет. Есть dbms_output.put_line - он обычно только для отладки. Так как выплевывает он только в Output ДАННОЙ текущей Oracle-сессии да и то если ты это незабыл включить.