web-dev-qa-db-ja.com

$ wpdbはテーブル列にNULLを挿入しません

こんなときに

    $status = NULL;

    $wpdb->update(
            'table',
            array( 
                'status' => $status,
            ), 
            array( 'id' => 1 ) 
    );

'status'列に、空の文字列''があるので、単にNULLに設定しません。

列はもちろんNULLでもかまいません。 $ wpdb-> queryと$ wpdb-> prepareもテストしましたが、結果は同じです。私は何か悪いことをしていますか?

12
Dejan Stosic

更新:

WordPress 4.4以降これはinsertupdatereplacedeleteおよびwpdbメソッドでサポートされ、チケット #15158 fixed としてクローズされました。

その更新について コメント - の@dmsnellに感謝します。

一方、wpdb::prepare()nullサポートは現在チケットでは wontfix としてクローズされています #12819

前回の回答:

NULLはサポートされていません。

NULLで値を更新するためにあなた自身のカスタムSQLを書かなければならないように見えます。

現在NULL$wpdb->prepare()によってサポートされていません。これは vsprintf format関数を介して入力を受け取ります。

これらのオープンTracチケットをチェックしてください:

これらのチケットは約4歳なので、これがコアによってサポートされるまで私は息を止めません;-)

@s_ha_dumが示唆しているようにソースを見てください。

考えられる回避策:

冒険好きなら、queryフィルタを使って以下を試すことができます。

    // Add a filter to replace the 'NULL' string with NULL
    add_filter( 'query', 'wpse_143405_query' );

    global $wpdb;
    $wpdb->update(
        'table',
        array( 
            'status' => 'NULL',
        ), 
        array( 'id' => 1 ) 
    );

    // Remove the filter again:
    remove_filter( 'query', 'wpse_143405_query' );

どこで

/**
 * Replace the 'NULL' string with NULL
 * 
 * @param  string $query
 * @return string $query
 */

function wpse_143405_query( $query )
{
    return str_ireplace( "'NULL'", "NULL", $query ); 
}

代わりに'NULL'よりももっとユニークな文字列を使いたくなるかもしれません。代わりに'###NULL###'を使ってください。

9
birgire

wpdb->updateはデフォルトですべてのデータ型の文字列になります。

フォーマット
(array | string)(オプション)$ dataの各値にマップされるフォーマットの配列。 stringの場合、そのフォーマットは$ data内のすべての値に使用されます。 省略すると、$ data内のすべての値は文字列として扱われます _ wpdb::$field_typesで特に指定されていない限り。

http://codex.wordpress.org/Class_Reference/wpdb#UPDATE_rows

フォーマットを指定できますが、指定可能な指定子は次のとおりです。

指定可能なフォーマット値 :%s文字列。整数(整数)としての%dと浮動小数点としての%f。省略した場合、$ whereのすべての値は文字列として扱われます。

http://codex.wordpress.org/Class_Reference/wpdb#UPDATE_rows

あなたは ソースを読み通すことができます そしてプロセスを解決することができます。

リターンの直前にSQLをダンプするためにwpdb->prepareメソッド(定期的にクリーンになる:)をハックすると、置換はwpdb->prepareの前に行われることがわかります。

string(48) "UPDATE `table` SET `status` = %s WHERE `id` = %s"

しかし、@ birgireが示唆しているように、その置き換えを促したのはprepareの限界かもしれません。

3
s_ha_dum

これを行う方法をWP 4.4以降でさらに説明します。 nullにするデータとフォーマット要素の両方をPHP 'null'値に設定する必要があります。

チケット #15158 の例は次のとおりです。

$wpdb->update($ttable, 
              [
                'user_id' => NULL,
                'status' => 'available',
                'update_time' => $now->format('Y-m-d H:i:s')
              ], [
                'therapist_id' => $therapist_id,
                'user_id' => $user_id,
                'start_time' => $ub['start_time']
              ], [
                 NULL,
                 '%s',
                 '%s'
              ], [
                 '%d',
                 '%d',
                 '%s'
            ]);
2
Mario Hendricks