如何使用一个查询更新多行(perl-mysql)?

时间:2010-06-29 14:52:17

标签: mysql perl rows

我需要使用一个查询更新多行。对于插入,我们通常会执行类似

的操作
INSERT INTO `table` (c1,c2,c3) VALUES 
 (1,2,3),
 (4,5,6),
 ..

然而,我们怎样才能为更新做类似的事情,其中​​每一行的值都不同于另一行?并且有一个条件与每行的id有关吗?

任何一个人都面临类似问题?

我现在必须进行更新的示例是:

UPDATE questions
SET lab='What sections do you believe the site must not have?',
    type='textarea',
    options=''
WHERE rnum=11;

UPDATE questions
SET lab='What is your favourate section?',
    type='radio',
    options='section1,section2,section3,section4,section5'
WHERE rnum=12;

等等。绝对这是最糟糕的方法,因为每个查询都需要执行,并且可能有多达20个。

5 个答案:

答案 0 :(得分:4)

使用占位符,您可以使用同一查询的多次执行来执行此操作:

my @data = (
  [ 'new_lab1', 'new_type1', 'new_opt1', 1 ],
  [ 'new_lab2', 'new_type2', 'new_opt2', 2 ],
);

my $sql = <<EOT;
UPDATE questions
SET lab=?,
    type=?,
    options=?
WHERE rnum=?
EOT

my $sth = $dbh->prepare($sql);
for my $datum (@data) {
    $sth->execute(@$datum);
}

答案 1 :(得分:1)

首先,为什么需要在一个查询中执行此操作?如果您需要以原子方式完成更新,可以将它们包装在START TRANSACTION;COMMIT;中吗?这可能就是我要做的事。

但是,如果您确实需要在一个查询中完成此操作,并且您要更新的行数相当小,则可以完成!你可以使用这个丑陋的小技巧:

UPDATE questions
SET
lab = IF(rnum=11, 'What sections...?',
        IF(rnum=12, 'What is your...?',
          IF(rnum=13, 'Etc.',
            NULL
          )
        )
      ),
type = IF(rnum=11, 'textarea',
         IF(rnum=12, 'radio',
           IF(rnum=13, 'Etc.',
             NULL
           )
         )
       )
WHERE rnum IN (11, 12, 13);

用perl编写循环来构造那个自然怪物的东西留作练习:)

如果你正确地写它并且如果表格是你所相信的那样,那么永远不应该使用那些剩余的NULL。为了增加安全性,您可能希望将这些列中的某些列声明为NOT NULL,如果您有能力,那么如果您的rnum不匹配,则分配将导致约束失败, UPDATE将被中止。

答案 2 :(得分:0)

考虑以下示例,它会增加列'col_name'的所有值,其id为&gt; 5和col_name不是0

id    col_name
1       1
5       2
6       3
7       5
8       6
9       7
10      0

查询

update tbl_name SET col_name=col_name+1 where id > 5 and col_name !=0

O / P将是

id    col_name
1       1
5       2
6       4
7       6
8       7
9       8
10      0

答案 3 :(得分:0)

如果您使用另一个表中的值更新一个表,则很容易:

update table1,table2
SET table1.value = table2.value
WHERE table1.key = table2_foreign_key

如果您通过以一致的方式更改行的子集来更新一个表,则很容易:

update table1
SET table1.value = (table1.value * 2)
WHERE table1.id in (SELECT id from table1 where table1.key > 50);

如果您尝试更新一个表中的多个记录,其中每个记录的更新方式不同,没有使用第二个表,则基本上不可能。最好在你的代码中完成它。

答案 4 :(得分:0)

随着时间的推移,我找到了一种更好的方法,通过一个查询,而不是使用for循环。 我们的想法是在重复更新时使用insert并将记录键放在插入上,这将强制查询进行更新。

INSERT INTO table_name 
                            (key, a, b) 
                            VALUES 
                            (1,'apple','orange'),
                            (2,'xyz','abc')
                            ON DUPLICATE KEY
                            UPDATE 
                            a= VALUES(a),
                            b= VALUES(b)