我无法以正确的格式获取信息架构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"
这里是一个正则表达式选项。有点杂乱,但是也会处理额外的空格。
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');
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
;
这是一个快速技巧,因为我已经对提取每个元素进行了硬编码,但是它可以在无参数的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' ;