我有以下查询:
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 :(得分: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)