2012-05-31 4 views
2

Сейчас я импортирующей и преобразования данных в базу данных Oracle следующим образом:Преобразование PL/SQL скрипт для хранимой процедуры

  • Программа, регулярно опрашивает определенные папки, если файл найден, он выполняет пакетный файл, который делает небольшое преобразование света в Python & bash, а затем вызывает SQL * Loader для загрузки CSV-файла в промежуточную таблицу.

  • Затем пакетный скрипт вызывает SQL-скрипт (через SQLPlus) для выполнения окончательного преобразования и вставляет преобразованные данные в главные таблицы для их соответствующей промежуточной таблицы.

Проблема с этим методом заключается в отсутствии обработки ошибок на стороне SQLPlus, например. если заявление «вставить в» не выполняется из-за нарушенного ограничения (или по любой другой причине), он все равно продолжит выполнение остальных утверждений, содержащихся в сценарии SQL.

В идеале, если возникло какое-либо исключение, я бы предпочел, чтобы все изменения были отброшены назад и детали исключения, вставленного в таблицу журналов etl.

Хранимые процедуры, по-видимому, хорошо подходят, поскольку обработка исключений встроена. Тем не менее, я борюсь с синтаксисом - в частности, как я могу использовать мои большие SQL-скрипты (которые представляют собой всего лишь комбинацию инструкций INSERT INTO, UPDATE, CREATE, DROP, DELETE и т. Д.) И бросают их в хранимую процедуру с некоторыми базовая обработка ошибок.

Что я надеюсь на это либо:

  • руководство быстрого & грязного манекена, чтобы принимать мой угнетающий сгусток PL/SQL и получить его для выполнения в хранимую процедуре или
  • Любой альтернативной (если хранимая процедура не подходит), которая предлагает ту же функциональность, т.е. способ выполнить кучу операторов SQL и откат, если какое-либо из этих утверждений выдает исключение.

О моих попытках - я пытался копировать части моих скриптов SQL в хранимую процедуру, но они всегда не компилироваться с ошибкой 'PLS-00103 Встречающегося символом, когда ожидает одно из следующих действий. например.

CREATE OR REPLACE PROCEDURE ETL_2618A AS 
    BEGIN 
     DROP SEQUENCE "METER_REPORTING"."SEQ_2618"; 
     CREATE SEQUENCE SEQ_2618; 
END ETL_2618A; 

Oracle документация не очень доступна и у меня не было много удачи с прибегая к помощи/поиска StackOverflow, но я прошу прощения, если я пропустил что-то очевидное.

+0

Не могли бы вы разместить свой код процедуры, а также точное сообщение об ошибке oracle возвращается – Satya

+0

Я уже предоставил их, см. Нижнюю часть сообщения. Полная ошибка: _PLS-00103: встречается символ «DROP» при ожидании одного из следующих: yadda yadda_ + _PLS-00103: встречается символ «END» _ – evanjd

+0

Следует отметить, что представленный код процедуры представляет собой очень небольшую часть сценария, который я пытаюсь сделать внутри процедуры, но я решил, что небольшой пример лучше, чем публикация всего скрипта. – evanjd

ответ

3

Чтобы выполнить DDL в PL/SQL, вам нужно использовать динамический sql.

CREATE OR REPLACE PROCEDURE testProc IS 
    s_sql VARCHAR2(500); 
BEGIN 
    s_sql := 'DROP SEQUENCE "METER_REPORTING"."SEQ_2618"'; 
    EXECUTE IMMEDIATE s_sql; 


    s_sql := 'CREATE SEQUENCE "METER_REPORTING"."SEQ_2618"'; 
    EXECUTE IMMEDIATE s_sql; 

EXCEPTION 

    WHEN OTHERS THEN 
     NULL; 
end testProc; 
/
+0

Спасибо за это. Выполнение этого для 60-70 заявлений довольно трудоемко, и учитывая, что мне не нужен мой динамический SQL, я не думаю, что есть простой способ обработки ошибок как части SQL-скрипта, даже если он Не следует использовать хранимые процедуры? – evanjd

+0

то, что я разместил, отлично подходит для DDL, для DML вы можете использовать их, как обычно, – Satya

+0

@evanjd: да вам нужен ваш динамический SQL. DDL не может быть выполнен «напрямую» в PL/SQL. –

0

Добавление обработки в PL/SQL прока или сценария исключение не сложно, но, конечно, требуется некоторое кодирование.Вот ваша процедура нарядила немного с некоторыми очень простым отчетом об ошибках добавили:

CREATE OR REPLACE PROCEDURE ETL_2618A AS 
    nCheckpoint NUMBER; 
BEGIN 
    nCheckpoint := 1; 

    EXECUTE IMMEDIATE 'DROP SEQUENCE "METER_REPORTING"."SEQ_2618"'; 

    nCheckpoint := 2; 

    EXECUTE IMMEDIATE 'CREATE SEQUENCE SEQ_2618'; 

    RETURN; 
EXCEPTION 
    WHEN OTHERS THEN 
    DBMS_OUTPUT.PUT_LINE('ETL_2618A failed at checkpoint ' || nCheckpoint || 
         ' with error ' || SQLCODE || ' : ' || SQLERRM); 
    RAISE; 
END ETL_2618A; 

Не тестируется на животных - вы будете первым! :-)

Смежные вопросы