Как я могу обновить несколько строк одним запросом (perl-mysql)? - PullRequest
1 голос
/ 29 июня 2010

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

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.

Ответы [ 5 ]

4 голосов
/ 29 июня 2010

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

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 голос
/ 14 августа 2010

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

0 голосов
/ 11 мая 2017

Со временем я нашел лучший способ сделать это и одним запросом вместо использования цикла 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 голосов
/ 29 июня 2010

Если вы обновляете одну таблицу значениями из другой таблицы, это просто:

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);

Если вы пытаетесь обновить несколько записей в одной таблице, где каждая запись обновляется по-разному, без с использованием второй таблицы, это в принципе невозможно. Лучше сделать это в своем коде.

0 голосов
/ 29 июня 2010

Рассмотрим следующий пример: он увеличивает все значения столбца 'col_name', чей id> 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...