0

列をNULL使用するように設定する方法はあり$wpdb->update();ますか?

私がしようとすると、WordPress はその列を float に型キャストしようとします。これは に変換NULLされ0ます。

コア コードと の内部を確認しましたが$wpdb->update()$formatパラメータは %s、%f、および %d のみを想定しています。$wpdb->field_types['myCol']に設定するところまで行きました'NULL'が、どちらも のクエリを中断するだけです$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. 必要なことを行う独自のデータベース クラスを作成します。$wpdbWordPress'をdrop-in に置き換えることができることはあまり知られていません。
于 2013-01-01T22:33:48.277 に答える
0

これは、insert() および update() を使用して SQL テーブルに null 値を挿入および更新できるようにするために、最新バージョンの wordpress から wpdb を変更するソリューションです。

/*
 * 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() を通常どおり使用します。

残りのWordpressや他のプラグインが期待するDBの動作を維持するために、デフォルトの$wpdbをオーバーライドするよりも、この方法で行うことを好みました。

于 2013-11-20T16:38:21.973 に答える