插入、更新或删除的 CASE 语句
Posted
技术标签:
【中文标题】插入、更新或删除的 CASE 语句【英文标题】:CASE statement for insert, update or delete 【发布时间】:2018-07-02 07:43:24 【问题描述】:我已经创建了存储过程。在那个存储过程中,我想要插入、更新或删除的 case 语句。
If v_var='I' then insert into main_tbl
If v_var='D' then delete from main_tbl where <condition>
If v_var='U' then update main_tbl set <condition>.
为此我创建了存储过程
create or replace procedure sp_cs as
v_var txt.col1%type;
type record is ref cursor return txt%rowtype; --Staging table
v_rc record;
cursor c1 is select * from txt;
begin
open c1;
loop
fetch c1 into v_rc;
for i in 1 .. v_rc.count
loop
select v_rc(i).col1 into v_var from txt;
case when v_var ='I' then
insert into main_tbl values (v_rc(i).col1, .....);
when v_var ='D' then
delete from main_tbl m where m.col2=v_rc(i).col2;
when v_var ='U' then
update main_tbl m set m.col2=v_rc(i).col2;
end case;
end loop;
end loop;
close c1;
end;
执行此操作后,数据无法加载到 main_tbl。你能帮我解决我的问题吗? 谢谢
【问题讨论】:
when
关键字丢失了两次。还有一个end
。
@jarlh 我已经完成了,但仍然遇到同样的问题。
create or replace sp_cs
实际上是 create or replace procedure sp_cs as
在你的真实代码中吗?
循环永远不会退出,因为没有exit when c1%notfound
来检查光标状态(尽管普通的Cursor FOR loop 会使这变得简单得多)。此外,v_var
永远不会设置为任何值。另外,v_rc
是记录而不是数组,所以不能有任何v_rc.count
或v_rc(i)
。
您没有为 v_var 设置任何值。在这种情况下,默认情况下它将为空。所以 case 语句永远不会满足。
【参考方案1】:
嗯,OPEN..FETCH..LOOP
已经过时了。您应该根据参数简单地使用单个插入/更新/删除语句。这将比您的循环构造更有效。
CREATE OR replace PROCEDURE sp_cs (p_var txt.col1%TYPE)
IS
BEGIN
CASE p_var
WHEN 'I' THEN
INSERT INTO main_tbl
SELECT *
FROM txt;
WHEN 'D' THEN
DELETE FROM main_tbl m
WHERE EXISTS (SELECT 1
FROM txt t
WHERE m.col2 = t.col2);
WHEN 'U' THEN
UPDATE main_tbl m
SET m.col2 = (SELECT v_rc.col2
FROM txt
WHERE m.somecol = t.somecol); -- the column you want to compare while updating
END CASE;
END;
/
虽然从您的更新查询中不清楚您想要实现什么,但我假设您在从 main_tbl
更新 col2 时在 txt
中有一个公共列。此外,我已将您的参数用作过程参数p_var
。如果您不想传递它,可以将其用作局部变量。
【讨论】:
【参考方案2】:您需要按原样声明您的过程,因此您在第一行缺少一个关键字:
create or replace PROCEDURE sp_cs
您缺少 WHEN
关键字和 END CASE
。
case when v_var = 'I'
then insert into main_tbl values (v_rc(i).col1, .....);
when v_var = 'D'
then delete from main_tbl m where m.col2=v_rc.col2;
when v_var = 'U'
then update main_tbl m set m.col2=v_rc.col2;
end case;
【讨论】:
【参考方案3】:创建过程有几个语法错误,试试下面的。 另外,看看Oracle MERGE
MERGE 可以在一个语句中执行 INSERT、UPDATE 和 DELETE。
CREATE OR REPLACE PROCEDURE sp_cs
IS
v_var txt.col1%TYPE;
TYPE record IS REF CURSOR
RETURN txt%ROWTYPE; --Staging table
v_rc record;
CURSOR c1
IS
SELECT * FROM txt;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_rc;
FOR i IN 1 .. v_rc.COUNT
LOOP
CASE
WHEN v_var = 'I'
THEN
INSERT INTO main_tbl
VALUES (v_rc (i).col1);
WHEN v_var = 'D'
THEN
DELETE FROM main_tbl m
WHERE m.col2 = v_rc.col2;
WHEN v_var = 'U'
THEN
UPDATE main_tbl m
SET m.col2 = v_rc.col2;
END CASE;
END LOOP;
END LOOP;
CLOSE c1;
END;
【讨论】:
【参考方案4】:这里需要 ref cur 吗?如果没有,那么试试这个
create or replace procedure sp_cs
as
cursor c1 is select * from txt;
rc c1%rowtype;
begin
For c in rc Loop
case c.col1
When 'I' Then
insert into main_tbl values (c.col1, .....);
When 'U' Then
update main_tbl m set m.col2=c.col2;
When 'D'
delete from main_tbl m where m.col2=c.col2;
End Case;
End Loop;
end;
【讨论】:
以上是关于插入、更新或删除的 CASE 语句的主要内容,如果未能解决你的问题,请参考以下文章
我收到存储更新、插入或删除语句影响了意外的行数 (0) 错误