Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQLite:如果没有';不存在?_Sqlite - Fatal编程技术网

SQLite:如果没有';不存在?

SQLite:如果没有';不存在?,sqlite,Sqlite,我确信我可以通过选择一行来检查它是否存在,但我想知道是否有一种更巧妙的方式,我只是不知道——这似乎是一个可能存在的足够常见的任务。此SQLite表如下所示: rowID QID ANID value ------ ------ ----- ------ 0 axo 1 45 1 axo 2 12 如果QID和ANID的组合已存在,则应更新该值;如果QID和ANID的组合不存在,则应插入该值。虽然写起来很简单: SELECT * wher

我确信我可以通过选择一行来检查它是否存在,但我想知道是否有一种更巧妙的方式,我只是不知道——这似乎是一个可能存在的足够常见的任务。此SQLite表如下所示:

rowID  QID    ANID  value
------ ------ ----- ------
0      axo    1     45
1      axo    2     12
如果QID和ANID的组合已存在,则应更新该值;如果QID和ANID的组合不存在,则应插入该值。虽然写起来很简单:

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

检查行是否存在,然后进行分支,或者插入/更新。我忍不住要寻找更好的方法。提前谢谢

您可以使用REPLACE命令

文档详细说明了一个替换选项

INSERT OR REPLACE INTO tabname (QID,ANID,value) VALUES ('axo',3,45)
“插入或替换”可以缩写为“替换”

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

在这种特殊情况下,事实证明没有简单的解决方案——至少我没有找到,尽管马克努力提出了一个解决方案

我最终使用的解决方案可能会对其他人有用,因此我将其发布在这里

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


我使用的实际代码使用prepare/placeholder和处理错误(如果代码不是23000等)要复杂一些。

注意:REPLACE实际上并不等于“UPDATE或INSERT”…REPLACE替换整行。因此,如果不为每列指定值,则将使用NULL或默认值替换未指定的列


在上面这样一个简单的例子中,这可能没什么问题,但是如果你养成了使用REPLACE作为“更新或插入”的习惯,那么当你忘记为每个字段指定一个值时,你就会删除数据……这只是经验中的一个警告

但这将更新
ROWID
值:据我从文档和测试中确定的,where子句在INSERT或REPLACED上不受支持。您确定已在表中正确声明主键吗?我已经修改了我的示例,但仍然无法重现您的问题
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'");
  }
}