затронутые строки в postgres с CodeIgniter

0

У меня есть следующий запрос:

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?

  • 0
    Можете ли вы показать полную схему для рассматриваемой таблицы?
  • 0
    Просьба посмотреть обновленный вопрос.
Показать ещё 2 комментария
Теги:
codeigniter

1 ответ

2
Лучший ответ

Да, это нормальное поведение.

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)
  • 0
    Большое вам спасибо .. это очень полезно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню