是否有将ARGUMENT_SIGNATURE转换为调用drop时使用的格式的函数

问题描述 投票:1回答:3

我无法以正确的格式获取信息架构PROCEDURES表的ARGUMENT_SIGNATURE,以便在drop语句中使用。

下面的完整示例:

具有创建的过程类似

create or replace procedure proc1(P1 FLOAT, P2 FLOAT) returns string
    language javascript as $$ $$;

从信息表/程序中选择:

SELECT PROCEDURE_NAME, ARGUMENT_SIGNATURE FROM TEST_DB.INFORMATION_SCHEMA.PROCEDURES
  WHERE PROCEDURE_NAME = 'PROC1' ;

产生以下结果

PROCEDURE_NAME ARGUMENT_SIGNATURE   
-------------- -------------------- 
PROC1          (P1 FLOAT, P2 FLOAT) 

用于删除PROC1过程的删除命令必须类似于:

drop procedure PROC1 (FLOAT, FLOAT)

所以这里的问题是我如何从“(P1 FLOAT,P2 FLOAT)”转到“(FLOAT,FLOAT)”?即有没有让我运行类似的功能:

SELECT PROCEDURE_NAME, ARGUMENT_SIGNATURE, SOMEFUNC(ARGUMENT_SIGNATURE) AS ARGTYPELIST
  FROM TEST_DB.INFORMATION_SCHEMA.PROCEDURES WHERE PROCEDURE_NAME = 'PROC1' ;

列ARGTYPELIST的格式应为(FLOAT,FLOAT)。

我已尝试使用regexp_replace,但似乎无法获得正确的答案。也许有更好的方法?我需要这是一个纯SQL解决方案。不需要保留字符“(“”)“。一些预期的输出

"(P1 FLOAT, P2 FLOAT)"  --> "FLOAT,FLOAT"
"()"                    -->  ""
"(P1 FLOAT)"            --> "FLOAT"

snowflake-data-warehouse
3个回答
1
投票

这里是一个正则表达式选项。有点杂乱,但是也会处理额外的空格。

SELECT REGEXP_REPLACE('(P1 FLOAT, P2 STRING)', '([(,]\\s*)\\w*\\s*(\\w*\\)?)', '\\1\\2'); 

返回

(FLOAT, STRING)

此版本将删除Parens:

SELECT REGEXP_REPLACE('(P1 FLOAT, P2 STRING)', '\\(?([,]\\s*)?\\w*\\s*(\\w*)\\)?', '\\1\\2'); 

0
投票

David的答案比这还干净,但是由于我对正则表达式不太满意,所以这是另一种选择:

SELECT 
    procedure_catalog,
    procedure_schema,
    procedure_name,
    argument_signature,
    '(' || array_to_string(array_agg(split_part(trim(value), ' ', 2)), ',') || ')'
from 
    database_name.INFORMATION_SCHEMA.PROCEDURES,
    lateral flatten (INPUT => SPLIT(trim(translate(ARGUMENT_SIGNATURE,'"()','')), ','))
WHERE 
    PROCEDURE_NAME = 'PROC1'
group by procedure_catalog, procedure_schema, procedure_name, argument_signature
;

0
投票

这是一个快速技巧,因为我已经对提取每个元素进行了硬编码,但是它可以在无参数的SP中正常工作,最多不带5个参数(您可以轻松扩展w /复制/粘贴。

CREATE or replace FUNCTION sp_param(PARMLIST VARCHAR)
    RETURNS VARCHAR
    LANGUAGE SQL
    AS 
    $$
     '(' ||
     REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY_SLICE(STRTOK_TO_ARRAY(PARMLIST, ' '),1,2),''),'\\)','') || 
     REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY_SLICE(STRTOK_TO_ARRAY(PARMLIST, ' '),3,4),''),'\\)','') || 
     REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY_SLICE(STRTOK_TO_ARRAY(PARMLIST, ' '),5,6),''),'\\)','') ||
     REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY_SLICE(STRTOK_TO_ARRAY(PARMLIST, ' '),7,8),''),'\\)','') ||
     REGEXP_REPLACE(ARRAY_TO_STRING(ARRAY_SLICE(STRTOK_TO_ARRAY(PARMLIST, ' '),9,10),''),'\\)','') ||
     ')'
    $$;

尝试一下:

SELECT PROCEDURE_NAME, ARGUMENT_SIGNATURE, sp_param(ARGUMENT_SIGNATURE) AS ARGTYPELIST
  FROM TEST_DB.INFORMATION_SCHEMA.PROCEDURES WHERE PROCEDURE_NAME = 'PROC1' ;
© www.soinside.com 2019 - 2024. All rights reserved.