0

有没有办法设置要NULL使用的列$wpdb->update();

当我尝试这样做时,WordPress 会尝试将该列类型转换为浮点数,然后转换NULL0.

我检查了核心代码和内部$wpdb->update()$format参数只需要 %s、%f 和 %d。我什至设置$wpdb->field_types['myCol']'NULL',但两者都只用于 break$wpdb->update()的查询(有趣的是,它会将每列的值转移到 之后NULL)。

这里有一个相关的问题,但该答案仅涉及INSERT而不 UPDATE涉及。

从数据完整性的角度来看,NULL这对于本专栏非常重要,因此我必须能够在必要时进行设置。

4

2 回答 2

1

正如您自己注意到的那样,该$format参数仅期望%s,%f%d。整个事情将通过prepare它也不需要null格式说明符,因为它基本上接受相同的格式说明符,(v)(s)printf但没有参数交换。你不能通过NULLupdate您具有与帖子中提到的相同的选择,建议为可能的重复项,本质上是这样。

  1. 只是不要使用该update功能。编写您自己的 SQL 并将其与$wpdb->query. 如果您正在处理自己的表格,那应该没问题。
  2. 创建您自己的数据库类,它将执行您想要的操作。一个鲜为人知的事实是,您可以将 WordPress' 替换$wpdbdrop-in
于 2013-01-01T22:33:48.277 回答
0

这是一个从最新版本的 wordpress 修改 wpdb 的解决方案,以便允许使用 insert() 和 update() 将空值插入和更新到 SQL 表中:

/*
 * Fix wpdb to allow inserting/updating of null values into tables
 */
class wpdbfixed extends wpdb
{
    function insert($table, $data, $format = null) {
        $type = 'INSERT';
        if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
            return false;
        $this->insert_id = 0;
        $formats = $format = (array) $format;
        $fields = array_keys( $data );
        $formatted_fields = array();
        foreach ( $fields as $field ) {
            if ( !empty( $format ) )
                $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
            elseif ( isset( $this->field_types[$field] ) )
                $form = $this->field_types[$field];
            else
                $form = '%s';

            //***edit begin here***
            if ($data[$field]===null) {
                unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare().  Without this, array would become shifted.
                $formatted_fields[] = 'NULL';
            } else {
                $formatted_fields[] = $form; //Original line of code
            }
            //***edit ends here***
        }
        $sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
        return $this->query( $this->prepare( $sql, $data ) );
    }

    function update($table, $data, $where, $format = null, $where_format = null)
    {
        if ( ! is_array( $data ) || ! is_array( $where ) )
            return false;

        $formats = $format = (array) $format;
        $bits = $wheres = array();
        foreach ( (array) array_keys( $data ) as $field ) {
            if ( !empty( $format ) )
                $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
            elseif ( isset($this->field_types[$field]) )
                $form = $this->field_types[$field];
            else
                $form = '%s';

            //***edit begin here***
            if ($data[$field]===null)
            {
                unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare().  Without this, array would become shifted.
                $bits[] = "`$field` = NULL";
            } else {
                $bits[] = "`$field` = {$form}"; //Original line of code
            }
            //***edit ends here***
        }

        $where_formats = $where_format = (array) $where_format;
        foreach ( (array) array_keys( $where ) as $field ) {
            if ( !empty( $where_format ) )
                $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
            elseif ( isset( $this->field_types[$field] ) )
                $form = $this->field_types[$field];
            else
                $form = '%s';
            $wheres[] = "`$field` = {$form}";
        }

        $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
        return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
    }

}
global $wpdb_allow_null;
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);

将此代码插入始终运行的地方,例如您的functions.php,然后照常使用新的全局$wpdb_allowed_null->insert() 和->update()。

我更喜欢这样做而不是覆盖默认的 $wpdb,以保留其余 Wordpress 和其他插件所期望的 DB 行为。

于 2013-11-20T16:38:21.973 回答