Oracle中实现ID存在则插单表否则插两表的SQL语句报错求解
报错原因
你写的IF/ELSE属于SQL的过程化语法,无法直接作为独立SQL语句执行,只能在存储过程、函数或者匿名PL/SQL/PL/pgSQL块中运行,这是你报invalid sql statement的核心原因。
解决方案1:使用匿名块执行(兼容Oracle、PostgreSQL)
Oracle 写法
DECLARE v_cust_exists NUMBER; BEGIN SELECT COUNT(1) INTO v_cust_exists FROM Customer_T WHERE CustomerID = 18; IF v_cust_exists > 0 THEN INSERT INTO Order_T VALUES(79,18,TO_DATE('09/28/2021','mm/dd/yyyy'),TO_DATE('10/01/2021','mm/dd/yyyy'),1,3); ELSE INSERT INTO Customer_T VALUES (18,'Capitol Industries Ltd', '999 Fifth Avenue', 'New York', 'NY','10015'); INSERT INTO Order_T VALUES (79,18,TO_DATE('09/28/2021','mm/dd/yyyy'),TO_DATE('10/01/2021','mm/dd/yyyy'),1,3); END IF; COMMIT; END; /
PostgreSQL 写法
DO $$ DECLARE v_cust_exists INT; BEGIN SELECT COUNT(1) INTO v_cust_exists FROM Customer_T WHERE CustomerID = 18; IF v_cust_exists > 0 THEN INSERT INTO Order_T VALUES(79,18,TO_DATE('09/28/2021','mm/dd/yyyy'),TO_DATE('10/01/2021','mm/dd/yyyy'),1,3); ELSE INSERT INTO Customer_T VALUES (18,'Capitol Industries Ltd', '999 Fifth Avenue', 'New York', 'NY','10015'); INSERT INTO Order_T VALUES (79,18,TO_DATE('09/28/2021','mm/dd/yyyy'),TO_DATE('10/01/2021','mm/dd/yyyy'),1,3); END IF; END $$;
解决方案2:使用MERGE语法(更通用,不需要写过程化逻辑)
MERGE是SQL标准语法,不需要嵌套过程逻辑,可以直接执行,同时完成判断和插入操作,以Oracle为例:
MERGE INTO Customer_T c USING dual ON (c.CustomerID = 18) WHEN NOT MATCHED THEN INSERT (CustomerID, CustomerName, Address, City, State, Zip) VALUES (18,'Capitol Industries Ltd', '999 Fifth Avenue', 'New York', 'NY','10015'); -- 上面MERGE保证客户一定存在,直接插入订单即可 INSERT INTO Order_T VALUES(79,18,TO_DATE('09/28/2021','mm/dd/yyyy'),TO_DATE('10/01/2021','mm/dd/yyyy'),1,3);
解决方案3:MySQL 专属写法
如果是MySQL环境,可以用INSERT IGNORE先保证客户存在,再插订单:
INSERT IGNORE INTO Customer_T VALUES (18,'Capitol Industries Ltd', '999 Fifth Avenue', 'New York', 'NY','10015'); INSERT INTO Order_T VALUES(79,18,STR_TO_DATE('09/28/2021','%m/%d/%Y'),STR_TO_DATE('10/01/2021','%m/%d/%Y'),1,3);
注意:需要保证CustomerID是Customer_T的主键或者唯一键,INSERT IGNORE才会生效
内容的提问来源于stack exchange,提问作者Noobie
相关产品推荐
相关产品推荐

