2010-06-29 2 views
1

Мне нужно обновить несколько строк одним запросом. Для вставки мы обычно делаем что-то вродеКак обновить несколько строк одним запросом (perl-mysql)?

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

Но как мы можем сделать что-то подобное для обновления, где каждая строка имеет различные значения, чем другие? И есть условие, связанное с идентификатором каждой строки?

Любой, столкнувшийся с подобной проблемой?

Пример того, как я должен сделать обновление сейчас:

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.

ответ

0

Со временем я нашел лучший способ сделать это и одним запросом вместо использования цикла for. Идея состоит в том, чтобы использовать вставку для повторного обновления и поместить в нее ключ записи, это заставит запрос выполнить обновление.

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

Рассмотрим пример, в котором он увеличил все значения столбца 'col_name', идентификаторы> 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 
+0

Извините, но это не то, о чем я прошу. Благодарю. – Luci

+0

нет, вы не можете сделать это, что хотите, используя один запрос. – Salil

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

Использование заполнителей, вы можете сделать это со многими казнями того же запроса:

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

первых, почему вы должны сделать это в одном запросе? Если вам нужны обновления, сделанные атомарно, можете ли вы их обернуть в 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 будет прервано.

Смежные вопросы