将列值从“男性”替换为“女性”,将“女性”替换为“男性”

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;

好吧,最后不是,因为正如其他人所指出的那样,您的每个更新语句都在更新表中的所有行,所以您最终会得到 malefemale 的所有内容,具体取决于它处理的行最后的。您需要确定要更新的特定行。一种方法是将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 updatewhere 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
)

【讨论】:

以上是关于将列值从“男性”替换为“女性”,将“女性”替换为“男性”的主要内容,如果未能解决你的问题,请参考以下文章

SQL查询将男性显示为“M”,女性显示为“F”[重复]

根据 NaN 将列值替换为 0 或 1 [重复]

从mysql表中选择每隔一行作为男性/女性

科学研究:女性比男性更优秀?

男性女性的心灵刮骨疗毒师

绘制虚拟变量时,如何将 x 轴上的 0.0,1.0 更改为男性女性?