С веб-сайта 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: вложенная хранимая процедура.