我一直在尝试在drupal中运行一个查询,如果它们已经存在则会更新条目,如果没有,则插入一个新条目。代码现在看起来像这样:
db_query("IF EXISTS (SELECT %d FROM {uc_posten_packages.pid})
UPDATE {uc_posten_packages} SET title = '%s', label = '%s', cost = '%d', length = '%d', width ='%d', height = '%d', weight = '%d' WHERE pid = %d
ELSE
INSERT INTO {uc_posten_packages} VALUES ('%d', '%s', '%s', '%d', '%d', '%d', '%d', '%d')",$id, $title, $label, $rate, $length, $width, $height, $weight, $id, $id, $title, $label, $rate, $length, $width, $height, $weight);
我看不出为什么该查询会抛出错误。错误中的所有数字都是正确的
...near 'IF EXISTS (SELECT 1 FROM uc_posten_packages.pid) UPDATE uc_posten_packages ' at line 1 query:
IF EXISTS (SELECT 1 FROM uc_posten_packages.pid) UPDATE uc_posten_packages SET title = 'vfbv', label = 'bbv', cost = '22', length = '232', width ='22', height = '22', weight = '22' WHERE pid = 1 ELSE INSERT INTO uc_posten_packages VALUES ('1', 'vfbv', 'bbv', '22', '232', '22', '22', '22')
这个查询是否有效和/或是否有更好的方法在drupal中处理这个问题?
答案 0 :(得分:6)
你正在寻找的是被称为“upsert”(更新否则插入),并且有一个drupal函数:db_merge。好在这里写一下:http://drupal.org/node/310085
drupal_write_record()不会自动执行“upsert”。它总是根据您传入的内容插入或更新,但不能同时插入或更新。
答案 1 :(得分:4)
[2013年1月更新]
这个答案指的是Drupal的旧版本,而不是当前的稳定版本。请通过添加这样的更新部分以及更多最新信息来编辑此答案,因为我不再使用Drupal或继续其API更改。
-semperos
[/ 2013年1月更新]
您有几个选项,即drupal_write_record
或运行示例查询并测试结果。这不应该在您的问题中的单个SQL查询中完成。
函数drupal_write_record
允许您指定要处理的表以及包含该表的每个列/字段的数据的对象(或关联数组)。如果您已经拥有要更新的行的主键,则将其作为函数的第三个参数包含在内,drupal_write_record
将自动使用SQL UPDATE
命令。否则,默认为INSERT
。例如:
drupal_write_record('uc_posten_packages', array('title' => "Foobar",
'label' => "foobar",
'cost' => 10,
'length' => 100,));
这将INSERT
包含该信息的新记录。如果您包含了array($pid)
的第三个参数,其中$pid
是充当表的主键的字段的名称,则它将执行更新。
此函数仅在您使用hook_schema
定义的表时才有效,对于任何具有数据库表的正确开发的Drupal模块都应如此。由于此函数使用模式来确保正确地写入数据库,因此应尽可能使用此函数(或者当不存在其他更具体的函数时,例如node_save
用于节点对象)。
您可以使用db_result(db_query("SELECT..."))
运行示例查询。如果没有找到结果,它将返回一个空字符串,在PHP中计算结果为false,因此您的代码可能如下所示:
if (db_result(db_query("SELECT * FROM {uc_posten_packages} WHERE pid = %d", $pid))) {
// UPDATE
} else {
// INSERT
}
答案 2 :(得分:1)
根据drupal_write_record,操作是UPDATE
或INSERT
,您需要知道在提交交易之前是否存在记录。这不是drupal_write_record()所做的。此函数只检查它的参数并相应地发出更新或插入。所以真的没办法来判断该函数是INSERT
还是UPDATE
。
解决方案是使用db_merge()查询,它是一个相对较新的SQL ANSI标准,完全符合我的需要(在MySQL的情况下,它在原子事务中执行)。
$return_value = db_merge('mytable')
->key(array('id' => $key))
->fields($fields)
->updateFields(array(
'updatedon' => $now,
))
->execute();
返回值是一个整数,对于插入返回1,对于更新返回2。
答案 3 :(得分:0)
这是替换语法的一个愚蠢的例子。
mysql> create table test (
-> id int,
-> a int,
-> b int,
-> unique (id)
-> ) engine = myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> replace into test (id,a,b) values (1,4,2);
Query OK, 1 row affected (0.00 sec)
mysql> replace into test (id,a,b) values (2,10,3);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+------+------+------+
| id | a | b |
+------+------+------+
| 1 | 4 | 2 |
| 2 | 10 | 3 |
+------+------+------+
2 rows in set (0.00 sec)
mysql> replace into test (id,a,b) values (1,5,5);
Query OK, 2 rows affected (0.00 sec)
mysql> select * from test;
+------+------+------+
| id | a | b |
+------+------+------+
| 1 | 5 | 5 |
| 2 | 10 | 3 |
+------+------+------+
2 rows in set (0.00 sec)
希望它可以帮助你。