SQL INSERT ... ON DUPLICATE KEY - return 仅新插入的行数,而不是新插入+更新的行数?
SQL INSERT ... ON DUPLICATE KEY - return number of only newly inserted rows, not number of newly inserted + updated rows?
我怎样才能得到这个?我知道我可以通过在 运行 这个插入查询之前获取所有行的 COUNT 来做到这一点,然后从 运行 这个插入查询之后的所有行的 COUNT 中减去它,但这对于大数据库来说并不实用。我还在 whosebug.com
上找到了这个公式
(numberOfValuesInInsert * 2) - mysql_affected_rows()
但它似乎对我不起作用,因为无论我更新还是插入新行,我都会受到影响 rows = 1
这是我的 node.js 代码 运行 在一个 FOR 循环中,所以在循环结束后我得到受影响的行的总和:
var sql = "INSERT INTO classdata (id, siteid, name, staff, locationname, start, end) VALUES ?
ON DUPLICATE KEY UPDATE
siteid=VALUES(siteid), name=VALUES(name), staff=VALUES(staff), locationname=VALUES(locationname), start=VALUES(start), end=VALUES(end)";
var values = [[id, siteId, name, staff, locationName, start,end]];
connection.query(sql, [values],function(err, results) {
if (!err) {console.log(new Date() + " : New data sucessfully inserted into classdata table. Affected rows: " + results.affectedRows);}});
affectedrows+= results.affectedRows;
它总是打印受影响的行:1,无论是插入还是更新记录。我在这里读到它应该 return 2 用于每个更新的记录,1 用于插入。
Getting number of rows inserted for ON DUPLICATE KEY UPDATE multiple insert?
我有一个PK,就是"id"字段,如果这对你有意义的话。
记录架构很重要。考虑以下因素。
架构
create table t1
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null
);
create table t2
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null,
unique key(thing)
);
create table t3
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null
);
还有这个PHP
(请注意,我使用旧的 mysql 函数只是为了演示,并不是说我会使用那个库)
但是,它具有与您的名字匹配的 mysql_affected_rows 功能。
PHP 例子
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dbname = 'so_gibberish';
$dbuser = 'myuser';
$dbpass = 'mypassword';
$dbhost = 'localhost';
$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
mysql_select_db('so_gibberish') or die("Could not open the db");
$test_query = "insert t1(thing,timesHere) values ('frog',1) on duplicate key update timesHere=timesHere+1";
$result = mysql_query($test_query) or die(mysql_error());
$numrows=mysql_affected_rows($link);
echo "affected rows=".$numrows."<br/>";
mysql_close($link);
如果我 运行 以上,它将始终 return 受影响的行为 1,因为我没有在索引中插入重复值,这会导致唯一键冲突。
记住,是唯一键冲突导致更新触发,而不是连续插入行。
但是如果我要修改PHP并使用table t2
,那么第一个运行会受到影响rows=1,此后相同数据影响行数=2
无论您的实际客户端代码是什么,如果您对您的模式有敏锐的眼光,您应该会看到这些结果
CLIENT_FOUND_ROWS
标志的值也可以影响它。请参阅以下内容link。
Mysql mysql_affected_rows()
上的手册页
节选:
For INSERT ... ON DUPLICATE KEY UPDATE statements, the affected-rows
value per row is 1 if the row is inserted as a new row, 2 if an
existing row is updated, and 0 if an existing row is set to its
current values. If you specify the CLIENT_FOUND_ROWS flag, the
affected-rows value is 1 (not 0) if an existing row is set to its
current values.
上面架构中的 table t3
呢?
好吧,如果我从 PHP 文件中插入 stmt
$test_query = "insert t3(id,thing,timesHere) values (1,'frog',1) on duplicate key update timesHere=timesHere+1";
那么是的,结果应该是一样的。 1 第一次测试,此后受影响的行数=2。
名为 timesHere
的列有什么意义?
那是为了证明增量有效并且更新发生了。
我怎样才能得到这个?我知道我可以通过在 运行 这个插入查询之前获取所有行的 COUNT 来做到这一点,然后从 运行 这个插入查询之后的所有行的 COUNT 中减去它,但这对于大数据库来说并不实用。我还在 whosebug.com
上找到了这个公式(numberOfValuesInInsert * 2) - mysql_affected_rows()
但它似乎对我不起作用,因为无论我更新还是插入新行,我都会受到影响 rows = 1
这是我的 node.js 代码 运行 在一个 FOR 循环中,所以在循环结束后我得到受影响的行的总和:
var sql = "INSERT INTO classdata (id, siteid, name, staff, locationname, start, end) VALUES ?
ON DUPLICATE KEY UPDATE
siteid=VALUES(siteid), name=VALUES(name), staff=VALUES(staff), locationname=VALUES(locationname), start=VALUES(start), end=VALUES(end)";
var values = [[id, siteId, name, staff, locationName, start,end]];
connection.query(sql, [values],function(err, results) {
if (!err) {console.log(new Date() + " : New data sucessfully inserted into classdata table. Affected rows: " + results.affectedRows);}});
affectedrows+= results.affectedRows;
它总是打印受影响的行:1,无论是插入还是更新记录。我在这里读到它应该 return 2 用于每个更新的记录,1 用于插入。 Getting number of rows inserted for ON DUPLICATE KEY UPDATE multiple insert?
我有一个PK,就是"id"字段,如果这对你有意义的话。
记录架构很重要。考虑以下因素。
架构
create table t1
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null
);
create table t2
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null,
unique key(thing)
);
create table t3
( id int auto_increment primary key,
thing varchar(100) not null,
timesHere int not null
);
还有这个PHP (请注意,我使用旧的 mysql 函数只是为了演示,并不是说我会使用那个库)
但是,它具有与您的名字匹配的 mysql_affected_rows 功能。
PHP 例子
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$dbname = 'so_gibberish';
$dbuser = 'myuser';
$dbpass = 'mypassword';
$dbhost = 'localhost';
$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to Connect to '$dbhost'");
mysql_select_db('so_gibberish') or die("Could not open the db");
$test_query = "insert t1(thing,timesHere) values ('frog',1) on duplicate key update timesHere=timesHere+1";
$result = mysql_query($test_query) or die(mysql_error());
$numrows=mysql_affected_rows($link);
echo "affected rows=".$numrows."<br/>";
mysql_close($link);
如果我 运行 以上,它将始终 return 受影响的行为 1,因为我没有在索引中插入重复值,这会导致唯一键冲突。
记住,是唯一键冲突导致更新触发,而不是连续插入行。
但是如果我要修改PHP并使用table t2
,那么第一个运行会受到影响rows=1,此后相同数据影响行数=2
无论您的实际客户端代码是什么,如果您对您的模式有敏锐的眼光,您应该会看到这些结果
CLIENT_FOUND_ROWS
标志的值也可以影响它。请参阅以下内容link。
Mysql mysql_affected_rows()
上的手册页节选:
For INSERT ... ON DUPLICATE KEY UPDATE statements, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag, the affected-rows value is 1 (not 0) if an existing row is set to its current values.
上面架构中的 table t3
呢?
好吧,如果我从 PHP 文件中插入 stmt
$test_query = "insert t3(id,thing,timesHere) values (1,'frog',1) on duplicate key update timesHere=timesHere+1";
那么是的,结果应该是一样的。 1 第一次测试,此后受影响的行数=2。
名为 timesHere
的列有什么意义?
那是为了证明增量有效并且更新发生了。