如何通过雪花存储过程传递 JSON 对象,然后循环遍历键值

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

我正在尝试将包含完全限定表的 JSON 对象传递到存储过程中,以便我可以循环遍历它并将键值放入表中。

CREATE OR REPLACE PROCEDURE proc_db.proc_schema.json_test(
    tables VARIANT
)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
DECLARE
    key_value_pairs VARIANT;
    keys_array ARRAY;
    key_value OBJECT;
    key STRING;
    database_name VARCHAR;
    table_for_tables VARCHAR;
    sql_command VARCHAR;
BEGIN

## parsing through the JSON object but commented out since it will parse in the FOR loop anyway
-- sql_command := (SELECT PARSE_JSON(:tables));

## create a table to put the extracted key values into
    table_for_tables := 'CREATE OR REPLACE TEMP TABLE proc_db.proc_schema.JSON_OBJECTS (DATABASE_NAME VARCHAR)';
    EXECUTE IMMEDIATE :table_for_tables;

## loop through the JSON object and put the extracted database_name into the DATABASE_NAME column in the table
    FOR key_value IN (SELECT PARSE_JSON(:tables))
    DO

## split the key value in the JSON from the first full stop to get database_name
        database_name := SPLIT_PART(:key_value, '.', 1);

## insert into the table
        sql_command := 'INSERT INTO proc_db.proc_schema.JSON_KEY_VALUES (DATABASE_NAME) VALUES('||:database_name||');';
        EXECUTE IMMEDIATE :sql_command;
        
  END FOR;
      
      RETURN 'Success!';
END;
$$;

这是调用块:

call proc_db.proc_schema.json_test(
      PARSE_JSON('{
        "tables": ["DB_PROD_1.DB_PROD_SCHEMA.DB_PROD_TABLE","DB_PROD.MY_SCHEMA.MY_TABLE", "DB_DEV.MY_SCHEMA.MY_TABLE_2"]
      }')
);

我想要的结果是在表中拥有一个包含 DATABASE_NAME、SCHEMA_NAME、OBJECT_NAME 的表,每个 object_type 位于正确的列下方,例如 DATABASE_NAME 下的 DB_PROD_1、DB_PROD、DB_DEV 等。

我收到错误“不允许执行 NULL 语句。”。我认为这可能与 SPLIT_PART 部分有关,因为当我在 FOR 循环之外设置 database_name 变量并尝试返回它时,

    database_name := SPLIT_PART(:key_value, '.', 1);
    RETURN :database_name;

它说“函数‘SPLIT_PART’的参数类型无效:(OBJECT, VARCHAR(1), NUMBER(1,0))”。不知道从这里去哪里。感谢任何帮助,谢谢!

json snowflake-cloud-data-platform variant
1个回答
0
投票

您需要更新代码

  1. 上面的脚本遗漏了很多雪脚本语法。
  2. 创建的表和插入的表不匹配。

下面是开始的脚本

CREATE OR REPLACE PROCEDURE json_test(
    tables VARIANT
)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
DECLARE
    key_value_pairs VARIANT;
    keys_array ARRAY;
    key_value OBJECT;
    key STRING;
    database_name VARCHAR;
    table_for_tables VARCHAR;
    sql_command VARCHAR;
BEGIN


-- parsing through the JSON object but commented out since it will parse in the FOR loop anyway
-- sql_command := (SELECT PARSE_JSON(:tables));

--# create a table to put the extracted key values into
    table_for_tables := 'CREATE OR REPLACE TEMP TABLE JSON_OBJECTS (DATABASE_NAME VARCHAR)';
    EXECUTE IMMEDIATE :table_for_tables;


    let query := '
    select value::varchar key from table (flatten(PARSE_JSON('''||tables||'''):tables::array)
      )';
    let rs resultset := (execute immediate :query);
    
    let   c1 CURSOR FOR rs;

-- loop through the JSON object and put the extracted database_name into the DATABASE_NAME column in the table
    FOR key_value IN  c1
    DO

    key := key_value.key;
-- split the key value in the JSON from the first full stop to get database_name
          select SPLIT_PART(:key, '.', 1) into database_name;
    
-- insert into the table
        sql_command := 'INSERT INTO JSON_OBJECTS (DATABASE_NAME) VALUES('''||:database_name||''');';
        EXECUTE IMMEDIATE :sql_command;
        
  END FOR;
      
      RETURN 'Success!';
END;
$$;

call json_test(PARSE_JSON('{
            "tables": ["DB_PROD_1.DB_PROD_SCHEMA.DB_PROD_TABLE","DB_PROD.MY_SCHEMA.MY_TABLE", "DB_DEV.MY_SCHEMA.MY_TABLE_2"]
          }'));


select * from JSON_OBJECTS;
© www.soinside.com 2019 - 2024. All rights reserved.