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

Is there an function translating the ARGUMENT_SIGNATURE to the format used when calling drop

我在以正确的格式获取信息架构过程 table 的 ARGUMENT_SIGNATURE 时遇到了麻烦,以便在删除语句中使用。

完整示例如下:

创建了一个类似

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

从信息中选择 SCHEMA/PROCEDURES:

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"

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

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

Returns

(FLOAT, STRING)

此版本将删除括号:

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

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
;

这是一个快速的 hack,因为我已经硬编码提取每个元素,但它在没有参数的 SP 上运行良好,最多 5 个参数(您可以轻松扩展 w/ copy/paste。

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' ;