如何在$ wpdb->时进行故障排除更新返回0

时间:2018-03-04 15:53:18

标签: mysql wordpress

我在wordpress网站上运行以下查询

$error = $wpdb->update( $table_name, 
                        array( 'value' => $update_value ), 
                        array( 'lead_id' => $lead_id, 
                               'field_number' => 31.3 ), 
                        array( '%s' ), 
                        array( '%d', '%f' )
               );

用于在用户最初提交表单后更新重力表单条目。此查询可以在24个字段中正常运行,但在2中返回0。

到目前为止,我尝试了以下问题排查步骤:

  1. 在查询后将结果存储为$error并运行var_dump($error);,它将返回0.
  2. 在查询后立即运行var_dump( $wpdb->last_query );,将生成的SQL字符串复制/粘贴到phpMyAdmin中,这也会报告0行受影响。
  3. 使用以下方法手动选择phpMyAdmin中的行: SELECT * FROM `table_name` WHERE `field_number` = 31.3 哪个也没有返回任何行。但是,我知道有些行匹配,因为我可以在表中找到它们。
  4. 使用与上述相同的查询手动选择另一个按预期更新的字段 - 此工作正常。
  5. $where_formatfloat更改为string。没有导致变化。检查数据库字段后,field_number字段将存储为浮点数。
  6. 使用$wpdb->prepare运行准备好的查询。仍然没有动静。 准备声明如下:
  7. $ error = $ wpdb->查询(     $ wpdb->制备(         “         更新         SET value =%s         WHERE lead_id =%d和field_number =%f         ”         $ table_name,$ update_value,$ lead_id,31.3     ) );

    var_dumped给出以下结果时:

    string '
                        UPDATE prefix_rg_lead_detail
                        SET `value` = 'a:3:{i:0;s:9:\"Liverpool\";i:1;s:10:\"Manchester\";i:2;s:5:\"Leeds\";}'
                        WHERE `lead_id` = 4 AND `field_number` = 31.300000
                        ' (length=188)
    

    我现在正处于我的智慧状态,因为我已经尝试了所有我能想到的东西,但仍然无法更新2个字段。

1 个答案:

答案 0 :(得分:1)

您的最终问题确实是FLOAT类型。这是一个不精确的价值,它会引导您解决问题。尽管数据库显示的值为31.3,但数据库内部最有可能是31.30000000000001,这就是where条件不起作用的原因。请查看此处的文档:Problems with Floating-Point Values

所以在路上让我们去测试:

create table test (
   n float
);
insert into test values (31.3);

mysql> select * from test;
+------+
| n    |
+------+
| 31.3 |
+------+
1 row in set (0.17 sec)

使用该值select对其运行31.3语句将评估为空:

mysql> select * from test where n=31.3;
Empty set (0.00 sec)

有几种方法可以在不改变列类型的情况下解决它:

1-使用ROUND(field,number_of_decimals)函数

mysql> select * from test where round(n,2)=31.3;
+------+
| n    |
+------+
| 31.3 |
+------+
1 row in set (0.00 sec)

2-将其转换为DECIMAL类型

mysql> select * from test where cast(n as decimal(5,2))=31.3;
+------+
| n    |
+------+
| 31.3 |
+------+
1 row in set (0.00 sec)

因此,为了使您的更新能够使用此数据,您必须在更新命令中使用以下选项之一,如:

$wpdb->query( $wpdb->prepare("UPDATE %s 
                                 SET value = %s  
                               WHERE lead_id = %d 
                                 AND round(field_number,2) = %f ", 
                             $table_name, 
                             $update_value, 
                             $lead_id, 
                             31.3 ) 
            );

我的建议是更改字段类型。 AFAIK没有任何情况下您的插件可能会因此更改而中断。它可能发生的是一个舍入值,就像你试图在(6,2)的十进制字段中插入31.696之类的值一样,它将成为31.67。另外不同的是,字段的值将被格式化为您选择的小数位数,因此31.3将开始显示为31.30您可以将其更改为:

alter table yourTableName modify field_name DECIMAL(6,2);

以下是对该解释的一些测试:

mysql> alter table test modify column n decimal(10,2);
Query OK, 1 row affected, 1 warning (0.90 sec)
Records: 1  Duplicates: 0  Warnings: 1

mysql> select * from test;
+-------+
| n     |
+-------+
| 31.30 |
+-------+
1 row in set (0.00 sec)

mysql> select * from test where n=31.3;
+-------+
| n     |
+-------+
| 31.30 |
+-------+
1 row in set (0.00 sec)

并显示四舍五入:

mysql> insert into test values (31.696);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from test;
+-------+
| n     |
+-------+
| 31.30 |
| 31.67 |
+-------+
2 rows in set (0.01 sec)