运行存储过程后,我收到错误

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

执行此存储过程后,我收到“STATMENT_ERROR”。

我正在尝试将 json 数据插入我的雪花表中:

CREATE SEQUENCE order_id_seq --START = 0 INCREMENT = 1;

CREATE TABLE orders 
(
    order_id NUMBER default order_id_seq.nextval,
    customer_id VARCHAR(10),
    order_date DATE,
    total_amount FLOAT,
    PRIMARY KEY (order_id)
);

-- Create the product table
CREATE TABLE products 
(
    order_id NUMBER ,
    name VARCHAR(100),
    quantity INT,
    unit_price FLOAT
);

CREATE OR REPLACE PROCEDURE insert_order_and_products(json_data VARIANT)
RETURNS STRING
LANGUAGE SQL
AS
$$
DECLARE
    order_id INTEGER;
BEGIN
    -- Step 1: Insert data into the orders table
    INSERT INTO orders (customer_id, order_date, total_amount)
    SELECT
        json_data:customer_id::VARCHAR(50) AS customer_id,
        TO_DATE(json_data:order_date::VARCHAR, 'YYYY-MM-DD') AS order_date,
        json_data:total_amount::FLOAT AS total_amount;

    -- Step 2: Get the order_id of the recently inserted order
    order_id := LAST_INSERT_ID();

    -- Step 3: Insert data into the products table
    INSERT INTO products (order_id, product_name, quantity, unit_price)
    SELECT
        order_id AS order_id,
        product.value:name::VARCHAR(50) AS product_name,
        product.value:quantity::INTEGER AS quantity,
        product.value:unit_price::FLOAT AS unit_price
    FROM
        (SELECT FLATTEN(json_data:products)) AS product;

    RETURN 'Data inserted successfully.';

END;
$$;


CALL insert_order_and_products(parse_json('{
    "customer_id": "C001",
    "order_date": "2024-04-26",
    "total_amount": 100.50,
    "products": [
        {
            "name": "Product A",
            "quantity": 2,
            "unit_price": 25.25
        },
        {
            "name": "Product B",
            "quantity": 1,
            "unit_price": 50.00
        }
    ]
}'));
sql json snowflake-cloud-data-platform
1个回答
0
投票

您的代码中存在多个问题:

  1. Snowflake中没有LAST_INSERT_ID()这样的函数。类似的是 LAST_QUERY_ID(),但是,它返回最后运行的查询 ID,而不是主键列的插入 ID。

您可以通过查询表来获取最后一次插入的ID:

select order_id into :order_id from orders order by order_id desc limit 1;
  1. 没有名为product_name的列,列名称为“name”

  2. 要访问变量JSON_DATA,需要添加“:”前缀,否则编译器将无法知道它是标识符还是变量。因此,您需要将以下查询更改为:

    INSERT INTO orders (customer_id, order_date, total_amount)
    SELECT
        json_data:customer_id::VARCHAR(50) AS customer_id,
        TO_DATE(json_data:order_date::VARCHAR, 'YYYY-MM-DD') AS order_date,
        json_data:total_amount::FLOAT AS total_amount;

    INSERT INTO orders (customer_id, order_date, total_amount)
    SELECT
        :json_data:customer_id::VARCHAR(50) AS customer_id,
        TO_DATE(:json_data:order_date::VARCHAR, 'YYYY-MM-DD') AS order_date,
        :json_data:total_amount::FLOAT AS total_amount;
  1. 以下查询在 SQL SP 中不正确:
    SELECT
        order_id AS order_id,
        product.value:name::VARCHAR(50) AS product_name,
        product.value:quantity::INTEGER AS quantity,
        product.value:unit_price::FLOAT AS unit_price
    FROM
        (SELECT FLATTEN(json_data:products)) AS product;

正确的做法是:

    SELECT
        :order_id AS order_id,
        product.value:name::VARCHAR(50) AS name,
        product.value:quantity::INTEGER AS quantity,
        product.value:unit_price::FLOAT AS unit_price
    FROM
        (SELECT * from table(FLATTEN(input => :json_data:products))) AS product;

将它们放在一起,完整代码如下:

CREATE OR REPLACE PROCEDURE insert_order_and_products(json_data VARIANT)
RETURNS STRING
LANGUAGE SQL
AS
DECLARE
    order_id INTEGER;
BEGIN
    -- Step 1: Insert data into the orders table
    INSERT INTO orders (customer_id, order_date, total_amount)
    SELECT
        :json_data:customer_id::VARCHAR(50) AS customer_id,
        TO_DATE(:json_data:order_date::VARCHAR, 'YYYY-MM-DD') AS order_date,
        :json_data:total_amount::FLOAT AS total_amount;

    -- Step 2: Get the order_id of the recently inserted order
    -- order_id := LAST_INSERT_ID();
    select order_id into :order_id from orders order by order_id desc limit 1;

    -- return :order_id;

    -- Step 3: Insert data into the products table
    INSERT INTO products (order_id, name, quantity, unit_price)
    SELECT
        :order_id AS order_id,
        product.value:name::VARCHAR(50) AS name,
        product.value:quantity::INTEGER AS quantity,
        product.value:unit_price::FLOAT AS unit_price
    FROM
        (SELECT * from table(FLATTEN(input => :json_data:products))) AS product;

    RETURN 'Data inserted successfully.';

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