SQLite:如果不存在,可以更新行或插入吗?

时间:2010-08-16 20:01:13

标签: sqlite

我确信我可以选择它来检查是否存在一行,但我想知道是否有一种我不知道的滑动方式 - 看起来像是一个足够普通的任务。这个SQLite表看起来像这样:

rowID  QID    ANID  value
------ ------ ----- ------
0      axo    1     45
1      axo    2     12

如果QID和ANID的组合已经存在,那么该值应该更新,如果QID和ANID的组合尚不存在,那么应该插入它。虽然它简单易写:

SELECT * where QID = 'axo' and ANID = 3;

并检查该行是否存在然后分支并插入/更新我不禁寻找更好的方法。提前谢谢!

4 个答案:

答案 0 :(得分:14)

小心:REPLACE并不等于'UPDATE OR INSERT'... REPLACE替换整行。因此,如果您没有为EVERY列指定值,则将使用NULL或默认值替换未指定的列。

在一个简单的例子中,如上所述,它可能很好,但是如果你习惯使用REPLACE作为'UPDATE OR INSERT',那么当你忘记为每个字段指定一个值时,你将会核数据...来自经验的警告。

答案 1 :(得分:10)

insert文档详细说明了REPLACE选项

INSERT OR REPLACE INTO tabname (QID,ANID,value) VALUES ('axo',3,45)

“INSERT OR REPLACE”可以缩写为REPLACE。

Perl中的示例

修订以下示例以使用复合主键

use strict;
use DBI;

### Connect to the database via DBI
my $dbfile = "simple.db";
unlink $dbfile;
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile");

### Create a table
$dbh->do("CREATE TABLE tblData (qid TEXT, anid INTEGER, value INTEGER, PRIMARY KEY(qid, anid))");

### Add some data
my $insert = $dbh->prepare("INSERT INTO tblData (qid,anid,value) VALUES (?,?,?)");

$insert->execute('axo', 1, 45);
$insert->execute('axo', 2, 12);

$insert->finish;

### Update data
my $insert_update = $dbh->prepare("REPLACE INTO tblData (qid,anid,value) VALUES (?,?,?)");

$insert_update->execute('axo', 2, 500);
$insert_update->execute('axo', 10, 500);

$insert_update->finish;

### Print out the data
my $select = $dbh->prepare("SELECT * FROM tblData ORDER BY 1,2");
$select->execute;

while (my @row = $select->fetchrow_array()) {
    printf "Row: %s\n", join(" - ", @row);
}

$select->finish;

$dbh->disconnect;
exit 0;

生成以下输出,演示一行的更新和另一行的插入

Row: axo - 1 - 45
Row: axo - 2 - 500
Row: axo - 10 - 500

答案 2 :(得分:4)

您可以使用REPLACE命令。 Docs

答案 3 :(得分:1)

在这种特殊情况下,事实证明没有简单的解决方案 - 至少不是我能够找到的,尽管马克努力提出建议。

我最终使用的解决方案可能对其他人有用,所以我在这里发布。

我已将多列主键定义为QID + ANID并尝试插入表中。如果存在该特定组合,则它将产生23000的错误代码,然后我可以使用指示它应该是UPDATE。这是基本的要点(在PHP中):

try {
  $DB->exec("INSERT INTO tblData (QID,ANID,value) VALUES ('xxx','x',1)");
}
catch(PDOException $e) {
  if($e->getCode() == 23000) {
    $DB->exec("UPDATE tblData SET value=value+1 WHERE ANID='x' AND QID='xxx'");
  }
}

我使用的实际代码使用prepare /占位符更复杂,如果代码不是23000等,则处理错误。

相关问题