我一直在尝试从我创建的表中添加变量(
table_name
),并希望它成为存储过程中的参数,如下所示。 table_name
来自不同的模式。但是,语法似乎不起作用。
我不知道我的语法有什么问题:
CREATE OR REPLACE PROCEDURE test(table_name string)
RETURNS TABLE ()
LANGUAGE SQL
EXECUTE AS CALLER
AS
DECLARE
res resultset;
schema_name1 := 'a';
schema_name2 := 'b';
destination_tbl1 VARCHAR(100);
destination_tbl2 VARCHAR(100);
destination_tbl3 VARCHAR(100);
rs resultset default (select 0);
query_str string;
BEGIN
destination_tbl1 := :schema_name1||'.c1';
destination_tbl2 := :schema_name2||'.c2';
destination_tbl3 := :schema_name2||'.c3';
query_str := 'select ID, ID_N from '|| :table_name;
rs := (execute immediate :query_str);
res := (with COD as (
select * from IDENTIFIER(:query_str))
, ALB as (
select COD.*,R.ID_N,
row_number() over (partition by COD.ID order by COD.ID) as ID
from COD
inner join IDENTIFIER(:destination_tbl1) R
on COD.ID_N=R.ID_N
)
, BCC as (
select COD.*,VSD.*
from COD
inner join IDENTIFIER(:destination_tbl2) VSD
on COD.ID=VSD.ID)
)
, data as (
select COD.*
from COD
left join (
select * from ALB where ID=1
) REG
on COD.ID_N=REG.ID_N
left join (
select * from BCC
) VS
on COD.ID=VS.ID
)
select ID
from data
order by ID);
return table(res);
END;
有几个问题,例如您定义了
rs
并使用 EXECUTE IMMEDIATE
代替 rs
,但稍后在代码中未使用 rs
。
我相信您想要获取
table_name
的列,这就是您定义query_str的原因,但您可以简单地在CTE COD中使用,如下所示
WITH COD AS (
SELECT ID, ID_N FROM ' || table_name || '
)
警告:请尽量不要使用
SELECT *
,因为它会导致很多问题,包括歧义和静默下游故障,而是使用SELECT COlS
还需要定义RETURN的结构和数据类型
CREATE OR REPLACE PROCEDURE test(table_name STRING)
RETURNS TABLE(ID NUMBER)
如果您想检查正在形成的动态查询,您可以使用
RETURN query_str
记得将返回类型设置为
STRING
CREATE OR REPLACE PROCEDURE test(table_name STRING)
RETURNS STRING
我创建了这个过程作为示例,我能够获取数据
CREATE OR REPLACE PROCEDURE test(table_name STRING)
RETURNS TABLE(ID NUMBER)
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
schema_name1 STRING DEFAULT 'a';
schema_name2 STRING DEFAULT 'b';
destination_tbl1 STRING;
destination_tbl2 STRING;
destination_tbl3 STRING;
query_str STRING;
res RESULTSET ;
BEGIN
destination_tbl1 := schema_name1 || '.c1';
destination_tbl2 := schema_name2 || '.c2';
destination_tbl3 := schema_name2 || '.c3';
query_str := '
WITH COD AS (
SELECT ID, ID_N FROM ' || table_name || '
),
ALB AS (
SELECT COD.ID, R.ID_N,
ROW_NUMBER() OVER (PARTITION BY COD.ID ORDER BY COD.ID) AS row_num
FROM COD
INNER JOIN ' || destination_tbl1 || ' R
ON COD.ID_N = R.ID_N
),
BCC AS (
SELECT COD.id, VSD.ID vsd_id
FROM COD
INNER JOIN ' || destination_tbl2 || ' VSD
ON COD.ID = VSD.ID
),
data AS (
SELECT COD.ID
FROM COD
LEFT JOIN ALB REG
ON COD.ID_N = REG.ID_N
LEFT JOIN BCC VS
ON COD.ID = VS.ID
)
SELECT ID
FROM data
ORDER BY ID;
';
res:= ( EXECUTE IMMEDIATE query_str );
RETURN TABLE (res);
-- return query_str ;
END;
$$;
调用程序
CALL test('MAIN_schema.input_table');
注意:由于使用
*
,您的 sql 查询可能会出现前面提到的错误,因为各个 CTE 的列名称相似,因此您需要修复这些错误。
输出