使用CodeIgniter的postgres中受影响的行


affected rows in postgres with CodeIgniter

>我有一个以下查询:

更新"用户"设置"first_name"='abc',"last_name"='',"移动"='988988888',"评论"='你好' 其中"id"='15'

以上数据已经在数据库中。 表示我在不更改任何数据的情况下提交表单。

我在终端中点击了上面的查询,它说: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)