У меня есть следующий запрос:
UPDATE "user" SET "first_name" = 'abc', "last_name" = '', "mobile" = '988988888', "comment" = 'Hello' WHERE "id" = '15'
и выше данные уже находятся в db. означает, что я представляю форму без изменения каких-либо данных.
Я опрокинул запрос в терминале, и он говорит: UPDATE 1
CI CODE:
$query = $this->db->get_where('user',array('id'=>$id),1);
if ($query->num_rows() > 0)
{
$this->db->update('user', $data, array('id'=>$id));
echo $afftected_rows = $this->db->affected_rows();exit;
}
DB SCHEMA(export using psql cmmand)
CREATE TABLE "user" (
id integer NOT NULL,
first_name character varying(50),
last_name character varying(50),
mobile character varying(50),
comment character varying(500)
);
Так в чем проблема? почему это возврат 1, даже если я не изменю никаких данных. это нормальное поведение для postgres?
Да, это нормальное поведение.
MySQL имеет понятие "сопоставленные строки" и "затронутые строки", которые могут различаться: когда "согласованная строка" будет обновлена с уже сохраненными значениями, это не повлияет.
В PostgreSQL возвращается только счетчик "затронутых строк", и все "сопоставленные строки" затронуты.
Чтобы быть полным, строго говоря, это поведение можно изменить в PostgreSQL. Пропуск этих обновлений всегда возможен с довольно общим триггером.
Пример:
Сначала базовое поведение по умолчанию сравнивается с:
test=> create table update_test(val text);
CREATE TABLE
test=> insert into update_test values('abc');
INSERT 0 1
test=> update update_test set val='abc';
UPDATE 1
Этот UPDATE 1 указывает на то, что затронута 1 строка, хотя значение одинаков.
Теперь позвольте сказать, чтобы пропустить строки, значения которых не изменяются.
-- generic trigger to void the update of one row
create function void_update() returns trigger language plpgsql as
'begin return null; end';
-- trigger affecting unchanged rows in a BEFORE UDPATE event
create trigger update_trigger
before update on update_test for each row
when (old is not distinct from new)
execute procedure void_update();
Теперь мы получаем поведение, похожее на MySQL:
test=> update update_test set val='abc';
UPDATE 0
0, потому что мы обновляем единственную строку таблицы со значением, которое оно уже имеет.
Повторите попытку с большим количеством данных, несколькими строками для пропусков, другими строками для изменения:
test=> insert into update_test values('def'),('ghi');
INSERT 0 2
test=> select * from update_test ;
val
-----
abc
def
ghi
(3 rows)
test=> update update_test set val='ghi';
UPDATE 2
Только 2 строки были затронуты, поскольку в последней строке уже содержится "ghi",
Убедитесь, что обновление действительно работает:
test=> select * from update_test ;
val
-----
ghi
ghi
ghi
(3 rows)