С веб-сайта Snowflake ниже о хранимой процедуре:



Работа с хранимыми процедурами — документация Snowflake
Хранимые процедуры позволяют расширить Snowflake SQL, комбинируя его с JavaScript, чтобы вы могли включать программные конструкции, такие как ветвление и циклы.



Итак, почему бы просто не использовать console.log(), хм?
Или PRINT (для пользователей SQL Server),
Или DBMS_OUTPUT.PUT_LINE для пользователей Oracle?

Почему это так сложно, что я должен определить таблицу журнала, бла, бла… https://docs.snowflake.com/en/sql-reference/stored-procedures-usage.html#logging-an-error-version -2

По крайней мере, данный пример не подходит для моей цели.

Как разработчику, мне часто приходится отлаживать, что является результатом функции/процедуры, почему происходит сбой (сообщение об ошибке), в какой строке происходит сбой.
В настоящее время Snowflake не соответствует этим требованиям.

Какой альтернативный вариант доступен?
Хорошо, это JavaScript. Я должен использовать это, особенно, {} и [] — объект и массив.

Лично я не считаю хорошей идеей использовать JavaScript вместо родного языка или языка поддержки фреймов данных, например Python. Отслеживание происхождения данных будет сильно отличаться от SQL, который можно преобразовать в AST.

CREATE OR REPLACE procedure MY_PROC(PARAM float)
  RETURNS VARIANT NOT NULL
  LANGUAGE JAVASCRIPT 
AS
$$
    try {
      var msg = [];
      msg.push({prc:'MY_PROC checkpoint 1:'+ new Date().toISOString(),txt:'test'});
      A= snowflake.execute({ sqlText:`select 1/`+ PARAM});
      A.next();    
      return_val = A.getColumnValue(1);
msg.push({prc:'MY_PROC checkpoint 2:'+ new Date().toISOString(),txt:'test finished.'});
      return {status:1, ret:return_val, msg:msg};
    }
    catch(err) {
        msg.push({prc:'MY_PROC checkpoint 3:'+ new Date().toISOString(),txt:'FAILED:' + err});
        return {status:0, ret:null, msg: msg};
    }
$$;

Объяснение, позвольте мне немного углубиться в фрагмент кода.

1) массив msg для хранения сообщения о выполнении, контрольная точка x…
2) возвращаемый объект функции: {status: 0, ret: placeholder, msg:[]}, где: статусуказывает, успешно ли запущена процедура.
ret: возвращает значение процедуры, msg: сохраняет сообщения.

Первый тест:

CALL MY_PROC(3);
Результат выглядит следующим образом:

{
  "msg": [
    {
      "prc": "MY_PROC checkpoint 1:2020-11-22T03:41:44.244Z",
      "txt": "test"
    },
    {
      "prc": "MY_PROC checkpoint 2:2020-11-22T03:41:44.322Z",
      "txt": "test finished."
    }
  ],
  "ret": 3.333330000000000e-01,
  "status": 1
}

status = 1 означает, что он был выполнен успешно, а возвращаемое значение равно 3,333330000000000e-01, как и ожидалось. Ага!

Второй тест:
CALL MY_PROC(0)

{
  "msg": [
    {
      "prc": "MY_PROC checkpoint 1:2020-11-22T03:13:33.884Z",
      "txt": "test"
    },
    {
      "prc": "MY_PROC checkpoint 3:2020-11-22T03:13:34.105Z",
      "txt": 'FAILED:Division by zero'
    }
  ],
  "ret": null,
  "status": 0
}

status = 0 означает, что он работал с ошибкой, а возвращаемое значение равно null, как и ожидалось. Бинго!

Итак, теперь я знаю, что где-то произошла ошибка между контрольной точкой 1 и контрольной точкой 3.

Это не идеальное решение, но мне оно подходит, я могу более эффективно отлаживать код.

Кроме того, я могу определить сложную функцию JavaScript в хранимой процедуре. Однако его нельзя использовать как обычную функцию или библиотеку, поэтому я бы не стал слишком усложнять его.

Ждите следующей статьи: Snowflake: вложенная хранимая процедура.