Исключение обработки для вызова процедуры нескольких магазинов в Snowflake - PullRequest
1 голос
/ 20 января 2020

У меня 3 магазина. У меня есть одна процедура хранения оркестровки с обработчиками ошибок с блокировками try catch. В каждом блоке перехвата я регистрировал пользовательскую ошибку в журнальной таблице, чтобы зарегистрировать ошибку, а затем я вызываю return() для выхода.

Но когда я вызываю эти 3 хранимые процедуры из процедуры хранения оркестровки, если любые ошибки / исключения генерируются, он записывает в журнал и затем выходит из этой процедуры хранилища. Затем он начинает выполнение следующей процедуры сохранения.

Но в моем случае, если возникнет какое-либо исключение, возникшее в какой-либо из процедур хранения в процедуре сохранения оркестровки, я хочу, чтобы он также завершил выполнение следующей процедуры. Затем он должен выйти из ORCH_SP.

Как мне этого добиться?

CREATE OR REPLACE PROCEDURE ORCH_SP()       
RETURN VARCHAR LANGUAGUE JAVASCRIPT      
AS $$ {      
    P1();       
    P2();       
    P3();       
} $$;      

Ответы [ 2 ]

0 голосов
/ 21 января 2020

Майк уже ответил на самое прямое изменение, которое вы можете сделать выше, проверив возвращаемые значения на наличие ошибок по содержанию. Ниже просто добавлен еще один возможный подход.

-

Показано в в некоторых примерах из документации Snowflake , процедура может завершиться с ошибкой вместо явный возврат.

Можно написать базовые процедуры (P1, P2, P3) в таком формате, где бросок автоматически действует как завершение без необходимости перехвата, и сохраняет контекст ошибки для любого прямого или косвенного CALL:

CREATE OR REPLACE PROCEDURE P1()       
RETURN VARCHAR LANGUAGUE JAVASCRIPT      
AS $$ {      
    // (… logic …)

    if (faultyCondition) {

      throw 'p1 failure reason';

    }

} $$;

-- Repeat above pattern for (P2, P3, etc.)    

Тогда вызывающая родительская процедура может быть написана следующим образом и прекратит выполнение при любой ошибке вместо продолжения:

CREATE OR REPLACE PROCEDURE ORCH_SP()       
RETURN VARCHAR LANGUAGUE JAVASCRIPT      
AS $$ {
  try {      

    // Note: Add more args / call directly as necessary for real-life use
    function run(call_name) { 
      snowflake.createStatement({ sqlText: `CALL $call_name();` }).execute();
    }

    run("P1");       
    run("P2");       
    run("P3");  

    // (… other logic …)

  } catch (err) {

    result = err;

  }

  return result;     

} $$;

Этот шаблон больше соответствует тому, как обработка ошибок обычно реализуется с использованием try-catch и подфункций.

0 голосов
/ 21 января 2020

Как насчет введения блоков try / catch в ORCH_SP () и проверки возвращаемого значения при каждом из вызовов дочерних SP, чтобы определить, следует ли повторно выдать ошибку, если она сгенерирована (и выйти), или перейти к вызову следующий SP ... Ниже приведен упрощенный пример, чтобы примерно проиллюстрировать подход:


CREATE OR REPLACE PROCEDURE ORCH_SP()       
RETURNS VARCHAR LANGUAGE JAVASCRIPT      
AS $$ {  
    var return_msg = "";
    try {
        var sp_call = "call P1()";    
        var result = snowflake.execute({sqlText: sp_call});  
        result.next();
        var return_msg = result.getColumnValue(1);
        if (return_msg!='SUCCESS') {
            throw return_msg;
        } 
        else {
            // call P2() and P3() from here...
            // perhaps in their own try/catch blocks
        }
    }
    catch (err) {
        return return_msg;
    }
    return return_msg;
} $$;  


CREATE OR REPLACE PROCEDURE P1()       
RETURNS varchar 
LANGUAGE javascript      
AS $$ { 
    var result = "SUCCESS";
    try {
        // comment/uncomment the next line to simulate success/failure
        throw 'naughty naughty';
    }       
    catch (err) {
      result = err;
    }
    return result;
} $$;  ```
...