使用CodeIgniter在postgres中受影响的行

时间:2014-12-04 15:06:02

标签: php postgresql codeigniter

我有以下查询:

  

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的正常行为吗?

1 个答案:

答案 0 :(得分: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

自上一行已包含'ghi'

以来,只有2行受到影响

检查更新是否确实有效:

test=> select * from update_test ;
 val 
-----
 ghi
 ghi
 ghi
(3 rows)