将列值从“男性”替换为“女性”,将“女性”替换为“男性”
Posted
技术标签:
【中文标题】将列值从“男性”替换为“女性”,将“女性”替换为“男性”【英文标题】:Replace a column values from 'male' to 'female' and 'female' to 'male' 【发布时间】:2013-07-31 11:20:42 【问题描述】:我有一张表,gender,其中只有两个条目,“男性”和“女性”只有这两个条目的行数。现在我想写一个程序来替换这两个值,输出应该如下,
Input Output
sex sex
------------------------
male female
female male
female male
male female
我正在创建一个程序,这给了我一个错误。我正在使用游标来获取多行。我知道我们可以只使用一个更新语句来做到这一点,但我想尝试这样。
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;
【问题讨论】:
@parado PLS-00306 调用“=”时参数的数量或类型错误 PLS-00324 游标属性可能不适用于非游标“v_gen” 不知道解决方案,但我会非常小心地更新所有行,就像您对语句所做的那样(我假设这不是意图):更新性别设置性别='女性'。顺便说一句,不要使用短信语言 您所做的如下:您只查看第一行(使用您的 FETCH .. INTO)然后更新所有行。我怀疑那是故意的...... 【参考方案1】:update Table1 set "col" = (case "col" when 'male' then 'female'
else 'male' end);
fiddle
【讨论】:
OP 说I knw that we can do it by using only 1 update statemen
【参考方案2】:
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 Female
update users set gender = (case when gender = 'Male' then 'Female' else 'Male' end);
【讨论】:
【参考方案3】:您所拥有的存在许多问题。 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;
好吧,最后不是,因为正如其他人所指出的那样,您的每个更新语句都在更新表中的所有行,所以您最终会得到 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
in the documentation 的更多信息。
【讨论】:
【参考方案4】:UPDATE table
SET gender = CASE gender
WHEN 'Male' THEN 'Female'
WHEN 'Female' THEN 'Male'
ELSE gender
END;
【讨论】:
点评来源:虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。我建议您查看 SO 的 official How to Answer article 以及来自 Jon Skeet 的综合 blog post。【参考方案5】:在您的情况下,我建议使用 Record 而不是 FETCH:
CREATE OR REPLACE PROCEDURE swap ()
IS
CURSOR cur_gender IS
SELECT * FROM gender;
rec_gender cur_gender%ROWTYPE;
BEGIN
FOR rec_gender IN cur_gender
LOOP
IF cur_gender%FOUND THEN
IF rec_gender.sex = 'male' THEN
UPDATE gender set sex='female'
WHERE idgender = rec_gender.idgender;
ELSE
UPDATE gender set sex = 'male'
WHERE idgender = rec_gender.idgender;
END IF;
-- COMMIT; --MAYBE?
END IF;
END LOOP;
END swap;
/
【讨论】:
【参考方案6】:请使用此查询将男性更新为女性,将女性更新为男性。 参考图片。
Table data before
语法
UPDATE <TABLE_NAME> set <COL_NAME> = (CASE <COL_NAME> WHEN '<DATA>' THEN'<DATA>' ELSE '<DATA>' END);
例子:
UPDATE users SET gender = (CASE gender WHEN 'Male' THEN 'Female' ELSE'Male' END);
Table data after
【讨论】:
这与之前的答案有何不同?【参考方案7】:执行此操作的 SQL 查询:
UPDATE table SET gender =
(CASE WHEN gender ='male' THEN 'female' else 'male' END)
【讨论】:
“继续”是什么意思? 这是对另一个答案的回应吗?【参考方案8】:甚至还有一种简单的方法可以做到这一点。您可以使用 DECODE
在 Oracle 数据库中执行此操作。
UPDATE GENDER SET SEX = DECODE(SEX, 'MALE', 'FEMALE', 'FEMALE', 'MALE');
上述查询将男性的性别更改为女性,将女性的性别更改为男性。
【讨论】:
这似乎比使用 for 循环(?)好得多。【参考方案9】: CREATE OR REPLACE PROCEDURE swap ()
IS
CURSOR cur_gender IS
SELECT * FROM gender;
BEGIN
FOR rec_gender IN cur_gender
LOOP
IF rec_gender.sex = 'male' THEN
UPDATE gender set sex='female' where sex='male';
ELSE
UPDATE gender set sex = 'male' where sex='female';
END IF;
END LOOP;
END swap;
【讨论】:
你用光标干什么? 声明 v_gen 性别.sex%type; cursor cur_gender 是从性别中选择性别;开始打开cur_gender;循环获取 cur_gender 到 v_gen; if v_gen='male' then --dbms_output.put_line('It was ' ||v_gen);更新性别设置性别='女'; elsif v_gen='female' then --dbms_output.put_line('It was ' ||v_gen);更新性别设置性别='男';万一; cur_gender%notfound 时退出;结束循环;关闭cur_gender;结尾;在这里它可以工作,但如果第一行是男性,那么它将男性设置为所有行,反之亦然,这是错误的【参考方案10】:update Employee
set Gender= case Gender when 'Male' then 'Female' when 'Female' then 'Male'
else
Gender
end
【讨论】:
【参考方案11】:/*Logic*/
SELECT Name, CASE
WHEN Gender = 'Male' THEN 'Female'
ELSE 'Male'
END
AS "NewGender"
FROM NameGender ;
/*Here NameGender is the name of the Table*/
【讨论】:
【参考方案12】:简单的创建一个表,让它成为人:
create table people(gender varchar2(10));
insert into people values('&gender');
假设输入是男、女、女、男:
select * from people;
GENDER
male
female
female
male
select decode(gender, 'male', 'female', 'female', 'male') sex from people;
SEX
female
male
male
female
【讨论】:
【参考方案13】:以下查询在Amazon Redshift 中运行良好。
update Table1 set gender =
(
select case when gender = 'male' then 'female'
when gender = 'female' then 'male' end
)
【讨论】:
以上是关于将列值从“男性”替换为“女性”,将“女性”替换为“男性”的主要内容,如果未能解决你的问题,请参考以下文章