有没有更简单的方法来获取雪花过程的参数类型列表?

Is there a simpler way to get the argument type list for a snowflake procedure?

我需要转移雪花程序的所有权 post 克隆到一个新角色。

为此,我使用了一个处理 database.information_schema.xxxx 视图中所有对象的过程。

虽然过程有问题,SHOW PROCEDURE 有一列将过程签名显示为参数类型,但 information_schema.procedures 视图显示实际参数名称及其参数类型,如果传递进入 GRANT 命令不起作用 - 授予仅需要参数类型签名,而不是参数名称:/

显示过程参数 => PROCEDURE_NAME(VARCHAR) RETURN VARCHAR INFORMATION_SCHEMA.PROCEDURES.ARGUMENT_SIGNATURE => PROCEDURE_NAME(P_PARAM1 VARCHAR)

我最终想到了这个很有趣,但感觉相当复杂,问题是 - 我是否错过了更简单的方法?

SELECT procedure_name
     , concat('(',listagg(argtype, '') within group (order by argindex)) cleanArgTypes
  FROM (SELECT procedure_name
             , argument_signature
             , lf.index argindex
             , lf.value argtype
          FROM rock_dev_test_1.information_schema.procedures
             , lateral flatten(input=>split(decode(argument_signature
                                                  ,'()','( )'
                                                       ,argument_signature
                                                  ),' ')
                              ,outer=>true) lf
          WHERE lf.index/2 != round(lf.index/2)
        )
GROUP BY procedure_name
         , argument_signature
ORDER by 1,2;

cleanArgTypes => (VARCHAR)

这将过度特定的 argument_signature 拆分为一个数组,使用 space 作为分隔符,然后将 return 集合横向展平成行,丢弃参数名称(始终在even index) 然后按参数名称和签名分组,并使用 ListAgg 将参数参数类型放回字符串中。

那个 () 中的小皱纹不起作用,因此必须转移到 ()

虽然我喜欢尝试 Snowflakes 的一些半结构化功能,如果有更简单的方法,我宁愿使用它!

大部分代码相同,但不需要嵌套,我从 arg_sig(输入)换成使用拆分的 SEQ,但大部分仍然相同:

SELECT p.procedure_name
    ,'( '|| listagg(split_part(trim(t.value),' ',2), ', ') within group (order by t.index) || ')' as out
FROM information_schema.procedures as p
    ,table(split_to_table(substring(p.argument_signature, 2,length(p.argument_signature)-2), ',')) t
group by 1, t.seq;

对于我的堆栈溢出模式中的玩具程序,我得到:

PROCEDURE_NAME OUT
DATE_HANDLER ( DATE)
TODAYS_DELIVERY_AMOUNT ( VARCHAR)
ABC ( TIMESTAMP_NTZ, TIMESTAMP_NTZ, VARCHAR)
ABC_DAILY ( )
STRING_HANDLER ( VARCHAR)

我认为没有 built-in 方法可以做到这一点。这是另一种方法:

with A as
(
select PROCEDURE_NAME, split(replace(trim(ARGUMENT_SIGNATURE, '()'), ','), ' ') ARGS
      ,ARGUMENT_SIGNATURE
from   test.information_schema.procedures P
)
select PROCEDURE_NAME
       ,listagg(VALUE::string, ',') as ARGS
from A, table(flatten(ARGS))
where index % 2 = 1
group by PROCEDURE_NAME
;

您还可以在 show 命令后使用结果扫描来获取单个字符串中的过程名称和参数签名:

show procedures;
select split("arguments", ')')[0] || ')' as SIGNATURE from table(result_scan(last_query_id()));