Sql 理解如何将异常与BEGIN和END一起使用时遇到困难

Sql 理解如何将异常与BEGIN和END一起使用时遇到困难,sql,postgresql,Sql,Postgresql,我是Postgres的新手,我正在尝试创建一个测试,测试以下查询的结果何时返回null,但我似乎无法正确获得它。我一直得到以下错误 ERROR: syntax error at or near "WITH" LINE 20: WITH expected (tran_id, sell_chan, total) AS (VALUES (3, 'St... 当我尝试运行以下代码时。请注意,如果我删除了BEGIN和END以及异常部分,那么其他所有部分都可以正常运行,从而获得预期的null查询 --

我是Postgres的新手,我正在尝试创建一个测试,测试以下查询的结果何时返回null,但我似乎无法正确获得它。我一直得到以下错误

ERROR:  syntax error at or near "WITH"
LINE 20: WITH expected (tran_id, sell_chan, total) AS (VALUES (3, 'St...
当我尝试运行以下代码时。请注意,如果我删除了BEGIN和END以及异常部分,那么其他所有部分都可以正常运行,从而获得预期的null查询

-- create test database
DROP TABLE IF EXISTS test_sales;
CREATE TABLE test_sales(
  tran_id INT PRIMARY KEY,
  chan_c VARCHAR(1),
  total FLOAT
);


-- populate test database
INSERT INTO test_sales VALUES (1, 'S', 99.99);
INSERT INTO test_sales VALUES (2, 'O', 99.99);
INSERT INTO test_sales VALUES (3, 'S', 100);
INSERT INTO test_sales VALUES (4, 'O', 100);
INSERT INTO test_sales VALUES (5, 'P', 99.99);
INSERT INTO test_sales VALUES (6, 'P', 100);

BEGIN
WITH expected (tran_id, sell_chan, total) AS (VALUES (3, 'Store', 100), (4, 'Online',100), (6,'Other',100))
SELECT tran_id, sell_chan, total INTO my_temp FROM (SELECT * FROM expected) AS q1 EXCEPT (SELECT tran_id,
                CASE chan_c
                WHEN 'S' THEN 'Store'
                WHEN 'O' THEN 'Online'
                ELSE 'Other'
                END sell_chan,
                total
                FROM test_sales AS q2 WHERE q2.total>=100) EXCEPTION WHEN NO_DATA_FOUND THEN NULL; 


END;
匿名块必须完成; 要插入到临时表中,首先必须创建它。 语法是INSERT INTO TABLE SELECT。。。不选择。。。进入 需要一个它所属的区块。 关于您的评论的旁注:表不是数据库! 尝试:


谢谢你,这消除了错误,帮助我理解发生了什么。但是,当查询返回为null时,不会触发异常。我将my_temp表修改为空,然后检查以确保主选择也是空的,方法是在最末端,在最后一个末端之外,从my_temp执行SELECT*,它是空的,正如预期的那样。异常不应该被触发吗?@thewayup不会触发,因为当您没有行并且确实从[…]或其他一些变体将列列表选择到严格目标中时,不会返回任何数据。无法使用此选项将数据插入现有表中。您可能希望查看找到的变量。顺便说一句,将插入测试_销售值1,'S',99.99,2,'O',99.99,3,'S',100,。。。;
-- create test table
DROP TABLE IF EXISTS test_sales;
CREATE TABLE test_sales(
  tran_id INT PRIMARY KEY,
  chan_c VARCHAR(1),
  total FLOAT
);


-- populate test table
INSERT INTO test_sales VALUES (1, 'S', 99.99);
INSERT INTO test_sales VALUES (2, 'O', 99.99);
INSERT INTO test_sales VALUES (3, 'S', 100);
INSERT INTO test_sales VALUES (4, 'O', 100);
INSERT INTO test_sales VALUES (5, 'P', 99.99);
INSERT INTO test_sales VALUES (6, 'P', 100);

DROP TABLE IF EXISTS my_temp;
CREATE TEMPORARY TABLE my_temp AS SELECT * FROM test_sales WHERE 1 <> 1;

DO
$$
BEGIN
  BEGIN
    WITH expected (tran_id, sell_chan, total) AS (VALUES (3, 'Store', 100), (4, 'Online',100), (6,'Other',100))
    INSERT INTO my_temp
    SELECT tran_id, sell_chan, total  FROM (SELECT * FROM expected) AS q1 EXCEPT (SELECT tran_id,
                    CASE chan_c
                    WHEN 'S' THEN 'Store'
                    WHEN 'O' THEN 'Online'
                    ELSE 'Other'
                    END sell_chan,
                    total
                    FROM test_sales AS q2 WHERE q2.total>=100);
  EXCEPTION WHEN NO_DATA_FOUND THEN
    NULL;
  END;
END;
$$
LANGUAGE plpgsql;