Drupal 7中的db_affected_rows for db_query


8

我只是注意到@Berdir非常适合db_affected_rows从Drupal 7中删除。我现在想知道现在最好的方法是检测您运行的查询是否更改了数据库中的任何内容。

一个典型的用例是。

db_query(...);
if (!db_affected_rows()) {
  db_query(...);
}

我看了从db_query返回的查询对象,但似乎并没有太大帮助。

更新:
我不清楚我在什么情况下需要该信息。

我当前的用例是一个非常简单的用例。我有一个带有nid列和一些数据列的节点类型表。我有一个表单,提交表单后,我想插入或更新数据库中的行。

db_update/ 的问题db_insert在于,如果我先使用update,并且在update返回0时插入,我将无法捕获条件,即使用db中的值提交表单。如果我先使用db_insert,则在数据库中已经存在一行的情况下,将引发en错误。

我想在这种特定情况下,我可以在创建节点时插入一个空白值,然后仅使用更新,但是在某些情况下,如果我需要存储键入到外部数据库的信息,这可能是不可能的。我还想避免必须依赖数据库值才能使代码起作用。

对于这种情况,我通常的策略是

db_query("INSERT IGNORE INTO ...")
if (!db_affected_rows()) {
  db_query("UPDATE ...");
}

无论数据库处于什么条件,这样做都是简单且无错误的。我现在看到的最佳选择是使用SQL处理它并执行以下操作:

db_query("INSERT ... ON DUPLICATE KEY UPDATE");

但是我希望数据库API能够处理此问题。

Answers:



8

深入研究之后,我发现Drupal为我的确切用例提供了一个现成的命名工具:

在数据库中插入一行,或者更新现有的数据库(如果已有的话)。

这称为合并查询,可以为某些数据库引擎自动完成。

合成文本非常简单:

db_merge('example')
  ->key(array('name' => $name))
  ->fields(array(
    'field1' => $value1,
    'field2' => $value2,
))
->execute();

是的,这是您更新的问题的正确答案:)请注意,合并查询已在D7开发周期的后期进行了重新设计,使其实际上像MERGE sql查询一样工作,这是SQL 2003标准的一部分,但尚无dbms实际实现,因此所有dbms都需要两个查询(通过使用事务使它们成为原子的)。用于MySQL的单一查询方法的问题在于,它完全忽略了key()定义,而仅使用给定表的唯一/主键。
伯迪尔2011年

@Berdir:感谢您指出正确的方向。我是那些喜欢编写SQL并且很难适应新的数据库API的开发人员之一:)
googletorp

感谢这个指针。但是,我不得不求助于db_query反正作为Drupal的DB API不使用常量像CURRENT_TIMESTAMP(见允许drupal.org/node/215821
威士忌
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.