【问题标题】:Snowflake SQL stored procedure to pass optional arguments雪花 SQL 存储过程传递可选参数
【发布时间】:2022-10-15 01:33:46
【问题描述】:

我们正在努力将 netezza 迁移到雪花。 Netezza 存储过程有一种方法,它允许在PROC_ARGUMENT_TYPES 的帮助下调用带有任意数量参数的过程。我们在雪花中也有类似的功能吗?

喜欢

c:= PROC_ARGUMENT_TYPES.count;

返回传递的参数数量。

请注意:我们正在处理 Snowflake 中的 SQL 存储过程。

【问题讨论】:

    标签: snowflake-cloud-data-platform


    【解决方案1】:

    Snowflake 不允许具有任意数量的输入参数的过程或 UDF。但是,可以使用过程重载、数组、对象和变体的任意组合来近似此功能。

    这是一个使用过程重载和变体的示例。第一个过程只有所需的参数。第二个过程具有必需的参数以及接受变体的附加参数。

    如果调用 SQL 指定了两个参数,它将调用签名中只有两个参数的过程(重载)。反过来,该过程只是调用为第三个参数指定 NULL 的主存储过程并返回结果。

    具有三个输入的主存储过程具有最终输入的变体。它可以接受一个数组或一个对象。数组需要输入的位置意识。一个对象没有。对象允许传递名称/值对。

    create or replace procedure VARIABLE_SIGNATURE(REQUIRED_PARAM1 string, REQUIRED_PARAM2 string)
    returns variant
    language javascript
    as
    $$
        var rs = snowflake.execute({sqlText:`call VARIABLE_SIGNATURE(?,?,null)`,binds:[REQUIRED_PARAM1, REQUIRED_PARAM1]});
        rs.next();
        return rs.getColumnValue(1);
    $$;
    
    create or replace procedure VARIABLE_SIGNATURE(REQUIRED_PARAM1 string, REQUIRED_PARAM2 string, OPTIONAL_PARAMS variant)
    returns variant
    language javascript
    as
    $$
        var out = {};
        out.REQUIRED_PARAM1 = REQUIRED_PARAM1;
        out.REQUIRED_PARAM2 = REQUIRED_PARAM2;
        out.OPTIONAL_PARAMS = OPTIONAL_PARAMS;
        return out;
    $$;
    
    -- Call the SP overload different ways:
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2');
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', array_construct('PARAM3', 'PARAM4', 'PARAM5'));
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', object_construct('PARAM3_NAME', 'PARAM3_VALUE', 'PARAM10_NAME', 'PARAM10_VALUE'));
    

    虽然这些 SP 是 JavaScript,但重载和数组、对象和变体的使用与 SQL 脚本存储过程的工作方式相同。

    【讨论】:

    • 所以基本上我们应该使用过程重载。唯一的问题是我们有大约 100 个 proc,现在我们必须深入了解它们是如何被调用的。但如果这是唯一的方法..那么就是这样..谢谢
    • 我不会在所有情况下都使用重载。根据情况,使用数组可能会更好;但是,至少目前没有任意数量的参数的选项。
    【解决方案2】:

    我在 Snowflake 中注意到了一些关于有效符号的事情。

    为了避免维护存储过程的重复、重载版本,重载的替代方法可能是在不需要其他值时要求传递某种可测试的虚假变体或 NULL。

        -- Call the SP by passing a testable, falsy value:
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2');                     -- This will fail fail without overloading with a matched, 2 string/varchar signature.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', NULL);               -- This will work.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', ''::variant);        -- This will work.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', array_construct());  -- This will work.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', object_construct()); -- This will work.
    

    当然array_construct('PARAM3', 'PARAM4', 'PARAM5'))也可以写成parse_json('["PARAM3", "PARAM4", "PARAM5"]')

    同样,object_construct('PARAM3_NAME', 'PARAM3_VALUE', 'PARAM10_NAME', 'PARAM10_VALUE') 也可以写成parse_json('{"PARAM3_NAME": "PARAM3_VALUE", "PARAM10_NAME", "PARAM10_VALUE"}')

    除非您比其他两个函数更喜欢 parse_json() ,否则这些替代方案都没有给我们任何有用的东西。

    另外,我不确定这是否一直有效(也许 Greg Pavlik 知道?),但是这些变体类型的符号可以通过使用{} 构造一个对象或使用[] 构造一个数组来稍微缩写,因此是变得更干净,更具可读性。

    为了探索 Snowflake 将接受的符号,以下是可以工作的代码示例:

    -- Call the SP using different notations:
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', (select array_construct('PARAM3', 'PARAM4', 'PARAM5')));           -- Make the notation awkward & hard to read.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', (select ['PARAM3', 'PARAM4', 'PARAM5']));                          -- Make the notation awkward & hard to read.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', ['PARAM3', 'PARAM4', 'PARAM5']);                                   -- This also works & is easy to read.
    call VARIABLE_SIGNATURE('PARAM1', 'PARAM2', {'PARAM3_NAME': 'PARAM3_VALUE', 'PARAM10_NAME': 'PARAM10_VALUE'}); -- This also works & is easy to read.
    

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      相关资源
      最近更新 更多