обновить несколько полей в БД

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Аватара пользователя
rem
Сообщения: 56
Зарегистрирован: 2011.11.22, 16:08

обновить несколько полей в БД

Сообщение rem »

здравствуйте. подскажите как обновить значение поля у нескольких строк?
в документации ничего не понятно. очень мало примеров, толком сложно разобраться.
в общем нужен пример запроса, чтобы обновить значение колонки 'col' у строк с 'id' номера которых будут указанны в массиве.
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: обновить несколько полей в БД

Сообщение esche »

rem писал(а):здравствуйте. подскажите как обновить значение поля у нескольких строк?
в документации ничего не понятно. очень мало примеров, толком сложно разобраться.
в общем нужен пример запроса, чтобы обновить значение колонки 'col' у строк с 'id' номера которых будут указанны в массиве.
Если без валидации - можно DAO использовать.. так примерно:

Код: Выделить всё

$command = Yii::app()->db->createCommand('Update {{table_name}} set col=:col where id=:id'); // своё имя таблицы
foreach ($cols as $id=>$col) { // подставить свой цикл
                    $command->execute(array(':col '=>$col,':id'=>$id));
}
 
Да.. если col для всех совпадает, то можно одним запросом -

Код: Выделить всё

 "Update {{table_name}} SET col='col_value' where id in (id1,id2...)" 
При составлении можно использовать addInCondition

С валидацией - в цикле по id получить модель, присвоить атрибут, сохранить атрибут.
http://yiiframework.ru/doc/guide/ru/form.table

Код: Выделить всё

$models = MyModel::model()->findAllByPk($ids); // массив id-шников для обновления
foreach ($models as $model) { // подставить свой цикл
$model->col = $col;
$model->save(array('col'));
}
p.s. смотрите API (ссылка в шапке)
...
TM123
Сообщения: 608
Зарегистрирован: 2011.06.09, 11:18

Re: обновить несколько полей в БД

Сообщение TM123 »

Если база принимает скрипты на обработку, то я бы сначала сформировал все update (если col одинаковые), а потом отправил бы на обработку, можно в транзакцию впихнуть, если есть опасность что обновление может не пройти. Последовательное выполнение update - путь убить сервер бестолковыми запросами. Если col, разные, может быть можно написать формулу и использовать один запрос.
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: обновить несколько полей в БД

Сообщение esche »

TM123 писал(а):Если база принимает скрипты на обработку, то я бы сначала сформировал все update (если col одинаковые), а потом отправил бы на обработку, можно в транзакцию впихнуть, если есть опасность что обновление может не пройти. Последовательное выполнение update - путь убить сервер бестолковыми запросами. Если col, разные, может быть можно написать формулу и использовать один запрос.
:mrgreen: Откуда информация про убийство сервера? Речь вроде не о 100500 запросов...
А можно в целях повышения.. В общем, поинтересоваться.. Что значит "база принимает скрипты на обработку"?
...
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: обновить несколько полей в БД

Сообщение Jampire »

rem писал(а):здравствуйте. подскажите как обновить значение поля у нескольких строк?
в документации ничего не понятно. очень мало примеров, толком сложно разобраться.
в общем нужен пример запроса, чтобы обновить значение колонки 'col' у строк с 'id' номера которых будут указанны в массиве.
Так вы не ту документацию читаете. Yii тут ни при делах. Вам надо читать что такое SQL и как с ним работать.
TM123 писал(а):Последовательное выполнение update - путь убить сервер бестолковыми запросами.
esche все правильно написал. Почитайте, что такое подготовленные запросы и в чем их преимущество.
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
Аватара пользователя
rem
Сообщения: 56
Зарегистрирован: 2011.11.22, 16:08

Re: обновить несколько полей в БД

Сообщение rem »

esche, спасибо за помощь. сделал с помощью DAO
TM123
Сообщения: 608
Зарегистрирован: 2011.06.09, 11:18

Re: обновить несколько полей в БД

Сообщение TM123 »

Откуда информация про убийство сервера? Речь вроде не о 100500 запросов...
А можно в целях повышения.. В общем, поинтересоваться.. Что значит "база принимает скрипты на обработку"?
2 запроса

update x set y=10, z='abc' where q=1

update x set y=10, z='abc' where q=2

выполняются дольше чем один запрос

update x set y=10, z='abc' where q=1;
update x set y=10, z='abc' where q=2;

Конкретно запрос такого вида можно переписать на и это будет еще быстрее

update x set y=10, z='abc' where q in (1,2)

Если y присваивается значение рассчитанное по простенькой формуле, то можно использовать запрос что-то типа
update x set y=y+1, z='abc' where q in (1,2)

Конечно формула расчета может быть очень сложной, но по возможности ее стоит воткнуть в запрос это все равно отработает быстрее.

Вообще следует приучать себя не пользоваться помойкой под названием Active Record для манипулирования данными за исключением выборки данных, она хороша только если не умеешь хорошо программировать или количество выполняемх операций с помощью нее очень мало. Недавний пример, один коллега обрабатывал логи, задача выполнялась от 1 до 20 минут, после исключения из процесса ActiveRecord и использования SQL скрипта, задача выполняется от 0.5 до 5 секунд.

P. S. Я всегда рассчитываю на то что либо будет много запросов, либо будет железо херовое, поэтому всегда стараюсь писать оптимальный код, чего и всем советую, такие советы и даю другим исходя из этого подхода.
Аватара пользователя
Stamm
Сообщения: 407
Зарегистрирован: 2010.03.14, 18:59
Откуда: Россия, Москва
Контактная информация:

Re: обновить несколько полей в БД

Сообщение Stamm »

А у меня немного другая точка зрения: писать сначала как мне удобно, т.е. используя AR. А там, где предполагается большое количество запросов или логи, или большое количество записей уже использовать plain sql.
byteasdf
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

Re: обновить несколько полей в БД

Сообщение byteasdf »

А почему никто не указал вот такого решения?

Код: Выделить всё

$criteria = new CDbCriteria();
$criteria->addInCondition('id',array(1,2));
Model::model()->updateAll(array('data'=>'test'),$criteira);
 
Обновляет все строки, которые удовлетворяют $criteria, устанавливая им data в test.
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: обновить несколько полей в БД

Сообщение esche »

.
TM123, прошу прощенья, не разглядел ответа на вопрос..
А можно в целях повышения.. В общем, поинтересоваться.. Что значит "база принимает скрипты на обработку"?
Улыбнуло (мышки плакали-кололись..):
TM123 писал(а):Вообще следует приучать себя не пользоваться помойкой под названием Active Record для манипулирования данными за исключением выборки данных, она хороша только если не умеешь хорошо программировать или количество выполняемх операций с помощью нее очень мало. Недавний пример, один коллега обрабатывал логи, задача выполнялась от 1 до 20 минут, после исключения из процесса ActiveRecord и использования SQL скрипта, задача выполняется от 0.5 до 5 секунд.
Про "помойку" - ИМХО, не совсем корректно, как минимум.

По сути. Любой инструмент хорош для решения определённых задач. AR позволяет быстро, удобно и понятно (за счёт небольшого объёма кода и логичного построения) решать многие типовые задачи (валидация, связи данных, поведения.. В общем, плюшек много). Надо полагать, что все возможности требуют некоторых затрат на память и процессорное время. Есть множество проектов/типов проектов, где такие расходы вполне приемлемы (как минимум, на первом этапе, до наплыва посетителей). А использование AR позволяет сократить время на создание рабочего прототипа, и в дальнейшем при необходимости(!) заняться оптимизацией узких мест.

В задачах импорта больших объемов данных, если не требуется валидация, связи.. в общем, возможности AR, правильно отказываться в пользу SQL-запросов через DAO-PDO (ну или mysql_query|mssql_query.. можно, блин, в сокеты самому писАть). Естественно, это менее затратно по ресурсам и выполняется быстрее (кстати, сравнение методов работы с БД проведено в книге у Sam-а - там же можно найти рекомендации по их применению). Однако это не повод называть AR помойкой и уж тем более пропагандировать отказ от неё "для всего", за исключением... обработки больших объёмов данных (при этом нет пояснения, что значит "очень мало" - это 2-3-10-100-500?). Хотя по сути своей мысль верна (если я правильно понял):

При больших объемах данных "чистый SQL" (обращение к БД через DAO или при помощи построителя запросов) даёт заметный выигрыш в производительности по сравнению с AR
TM123 писал(а):P. S. Я всегда рассчитываю на то что либо будет много запросов, либо будет железо херовое, поэтому всегда стараюсь писать оптимальный код, чего и всем советую, такие советы и даю другим исходя из этого подхода.
При редактировании одного пользователя, если явно не требуется 100500 запросов, выигрыш от замены AR на SQL (если таковой будет с учётом аналогичного функционала) не будет ощутим для пользователя (в сравнении со временем загрузки страницы). Зато время написания кода (собственной валидации, например) увеличится значительно. Не вижу смысла в таком случае отказываться от AR. Формулировка "обновить несколько полей" на мой взгляд ближе к ситуации с небольшим количеством запросов.

РуStamm, полагаю, эта точка зрения присуща многим - логично оптимизировать узкие места.. (Естественно, это не повод делать всё "абы как" и преднамеренно расставлять пустые циклы и delay|pause :) ) В общем, про плюсы и минусы "преждевременной оптимизации" можно нагуглить.
...
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: обновить несколько полей в БД

Сообщение slavcodev »

esche писал(а):(мышки плакали-кололись..)

оффтоп: разве мышки, не ёжики? :lol:
Жду Yii 3!
TM123
Сообщения: 608
Зарегистрирован: 2011.06.09, 11:18

Re: обновить несколько полей в БД

Сообщение TM123 »

Прием скриптов на исполнение.

Не все базы данных принимают на исполнение скрипты.

1. MySQL - она не может выполнить за один раз более одной SQL команды, за исключением случаев программирования функций на стороне сервера. Это означает что MySQL не принимает на обработку скрипты, только единичные SQL команды, хотя возможно вы их называете скриптами. Кстати MySQL клиенты просто имеют удобную феньку последовательного выполнения команд, но это не скрипт.
2. PostgreSQL - она принимает на исполнение простенькие скрипты состоящие из базового набора SQL команд S-U-I-D, однако написание полноценных скриптов возможно только при разработке хранимых функций.
3. MS SQL и Oracle - принимают на исполнение полноценные скрипты с возможностью определения переменных, организации курсоров, циклов, проверки условий в общем все то, что позволяют Postgres и MySQL только при программировании на стороне сервера.

Это называется почувствуйте разницу, я со всеми перечисленными базами работал с базами размером от гига до нескольких десятков гигов и сотнями обращений в секунду и поверьте что я знаю что говорю. Задача решаемая с использованием PHP или .NET может работать до часа, при этом грамотно написанный SQL скрипт решает ее за 1-2 минуты и скрипт этот может быть в несколько тысяч строк - это вполне нормально.

Относительно ActiveRecord - это средство позволяющее вовлечь в процесс программирования низкоквалифицированных программистов, позволяющее им выполнять типовые задачи с минимальным количество ошибок с минимальными затратами времени, но это средство отнюдь не позволяет писать быстрый и эффективный код, т.к. цели его другие. Это уместно в условиях дефицита рабочей силы в мире и интеллектуально развитых людей с потенциалом, в конце концов не всем быть инженерами, производительность некоторых можно повысить выдав вместо кувалды с киркой отбойные молотки и в определенных случаях, как вы правильно заметили, они эффективнее карандаша и линейки. Вопрос только в том чего вы хотите достигнуть, умело обращаться с отбойным молотком и все вокруг крушить - ну это ваше право и позиция компании Microsoft вам в помощь, если у нас тормозит один сервер, мы поставим 2. Мне ближе позиция отмерить по линейке, нарисовать карандашиком крестик и стукнув обычным молотком обвалить ровно столько породы, сколько мне нужно.

Развязывать тут holywar я не собираюсь, потому что все очные holywar со своими коллегами на эту тему я выйграл на конкретной практике а не пустых рассуждениях из области высоких материй. В теории может и красиво все, а практика она совсем другая, а я практик а не теоретик и практик с большим опытом.
Аватара пользователя
mat.twg
Сообщения: 222
Зарегистрирован: 2012.02.22, 20:44
Откуда: Санкт-Петербург

Re: обновить несколько полей в БД

Сообщение mat.twg »

byteasdf писал(а):А почему никто не указал вот такого решения?

Код: Выделить всё

$criteria = new CDbCriteria();
$criteria->addInCondition('id',array(1,2));
Model::model()->updateAll(array('data'=>'test'),$criteira);
Обновляет все строки, которые удовлетворяют $criteria, устанавливая им data в test.
Единственное зерно в топике...
Ответить