我有一个表,性别,其中只有两个条目,‘男性’和‘女性’的行数与这两个条目。现在我想编写一个过程来替换这两个值,输出应该如下所示,
Input Output
sex sex
------------------------
male female
female male
female male
male female我正在创建一个过程,这给了我一个错误。我使用游标获取多个行。我知道我们只需要使用一个update语句就可以做到这一点,但是我想尝试这样做。
declare
v_gen gender%rowtype;
cursor cur_gender is
select * from gender;
begin
open cur_gender;
loop
fetch cur_gender into v_gen;
select * from gender;
if v_gen='male'
then
update gender set sex='female';
else
update gender set sex='male';
end if;
exit when v_gen%notfound;
end loop;
close cur_gender;
end;发布于 2013-07-31 11:31:12
update Table1 set "col" = (case "col" when 'male' then 'female'
else 'male' end);http://www.sqlfiddle.com/#!4/827b4/1
发布于 2016-02-02 04:38:38
ID Username Email Gender
1 sanjay sanjay@gmail.com Male
2 nikky nikky@gmail.com Male
11 raj raj@gmail.com Female
12 Rahul rahul@gmail.com Femaleupdate users set gender = (case when gender = 'Male' then 'Female' else 'Male' end);发布于 2013-07-31 14:03:27
你拥有的东西有很多问题。产生PLS-00324的直接原因是v_gen是一个记录,因此您需要将一个字段与该记录与您的固定值进行比较,而不是将整个记录:
if v_gen='male'变成了
if v_gen.sex = 'male'然后,您有一个虚假的select * from gender,它看起来像一个意外,需要完全删除。
最后,您将%notfound应用于记录,而不是游标:
exit when v_gen%notfound;变成了
exit when cur_gender%notfound;嗯,不完全是最后,因为正如其他人所注意到的,每个update语句都在更新表中的所有行,因此,根据其最后处理的行,您将以male或female的形式结束所有操作。您需要标识要更新的特定行。一种方法是将rowid作为游标的一部分进行查询,但是有一种内置方式更容易实现:
declare
cursor cur_gender is
select * from gender
for update;
begin
for v_gen in cur_gender
loop
if v_gen.sex='male'
then
update gender set sex = 'female'
where current of cur_gender;
else
update gender set sex = 'male'
where current of cur_gender;
end if;
end loop;
end;
/SQL Fiddle。
或者您可以通过使用case而不是if来简化它。
declare
cursor cur_gender is
select * from gender
for update;
begin
for v_gen in cur_gender
loop
update gender
set sex = case v_gen.sex when 'male' then 'female' else 'male' end
where current of cur_gender;
end loop;
end;
/..。它非常接近于您已经知道的单一更新语句方法。该版本的SQL Fiddle。
您可以阅读更多关于for update和where current of 在文件中的信息。
https://stackoverflow.com/questions/17968933
复制相似问题