我试图辨别replace into
查询是否导致直接写入,或者首先删除然后写入。
The MySQL docs say受影响的行数应该在前者的情况下返回1,在后者的情况下应该返回1:
受影响的行计数可以轻松确定是否更新REPLACE 只添加了一行或者它是否也替换了任何行:检查是否 计数为1(已添加)或更高(已替换)。
但是,对于我来说,通过PHP和MySQLI执行此操作时,无论我的查询是直接写入还是首先删除然后写入,值都始终为1。
我有一张桌子" foo"使用一列:varchar也是主键。所以从一开始就是空的。我跑:
$sql = "REPLACE INTO foo VALUES('bar');"
$db->query($sql); //$db is an instantiated and working MySQLI instance
echo $db->affected_rows;
这给了我" 1" - 公平地说,这是一个直写。但是,如果我再次运行相同的查询,它应该给我" 2",对吗?首先删除该行,然后重新插入,因为主键是相同的。因此,2个受影响的行。
顺便说一句,我已经尝试了基本查询和准备好的陈述,即
$sql = "REPLACE INTO foo VALUES(?)";
$stmt = $db->prepare($sql);
$bar = "bar";
$stmt->bind_param('s', $bar);
$stmt->execute();
echo $stmt->affected_rows; //still 1
有什么想法!?
答案 0 :(得分:0)
根据我的实验和发现:
就像手册中所说的那样,如果REPLACE
删除了一行并插入到位而不是INSERT
,它会显示更多的数字。请注意文档:
请注意,除非表具有PRIMARY KEY或UNIQUE索引,否则使用 REPLACE语句毫无意义。它等同于INSERT, 因为没有索引可用于确定是否有新行 复制另一个。
因此,在replace
语句中,您必须传递主键或唯一键列的值。从我看来,你只传递一个值。您需要为REPLACE
指定一个键值,以便在替换/插入之前识别应检查哪个行值。
另一个有趣的观点是:
如果单行可以替换多个旧行 该表包含多个唯一索引和新行重复项 不同唯一索引中不同旧行的值。
这会产生大于2的数字,并且当您向其传递多个唯一列值时就是这种情况。
在运行了几个测试后,只传递了你所做的唯一键值,这就是我发现的:
1)如果您的其他列包含某些值(非默认值)并且您正在使用REPLACE语句仅传递唯一键值,则会设置所有其他列值到他们的DEFAULT值,因此受影响的行 2 。 REPLACE删除现有行,因为该行包含REPLACE语句中未提及的值。
请注意以下文档:
所有列的值都取自中指定的值 REPLACE声明。任何缺少的列都设置为默认值 值,就像INSERT一样。
2)如果所有其他列值都是默认值,则使用仅传递唯一键值的REPLACE语句会导致 1 。现在, 1 的原因我相信可以成为以下之一:
已进行更新(Update bar set foo=1 where foo=1
成功时返回TRUE(1),但受影响的行数为0)
REPLACE永远不会返回0(假设返回-1)
所以基本上,你得到一个 1 ,因为你的所有其他列都已经设置了默认值,如果更改任何其他列值并再次运行相同的语句,你会发现结果是 2 。