使用表中的变量添加到 Snowflake 中的存储过程

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

我一直在尝试从我创建的表中添加变量(

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;
sql scripting snowflake-schema
1个回答
0
投票

有几个问题,例如您定义了

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 的列名称相似,因此您需要修复这些错误。

输出

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.