webentwicklung-frage-antwort-db.com.de

So definieren Sie zusammengesetzte Schlüssel mit dbDelta ()

Beim Versuch, eine Tabelle mit dbDelta() und zusammengesetztem Primärschlüssel zu erstellen, wird eine Fehlermeldung angezeigt. Die SQL ist ziemlich einfach.

$sql = "CREATE TABLE {$wpdb->prefix}voicemail_call (

    user_id BIGINT(9) UNSIGNED NOT NULL,
    call_id BIGINT(9) UNSIGNED NOT NULL,
    opened BOOL DEFAULT 0 NOT NULL,

    PRIMARY KEY  (user_id, call_id)
    );";

dbDelta($sql);

Dies zeigt Fehler

WordPress database error: [Multiple primary key defined]
ALTER TABLE wp_voicemail_call ADD PRIMARY KEY (user_id, call_id)

Mache ich es falsch? Wie definiere ich den zusammengesetzten Primärschlüssel mit dbDelta richtig?

Hinweis: Obwohl der Fehler angezeigt wird, wird dennoch die Tabelle erstellt, in der beide Spalten als Primärschlüssel festgelegt sind.

4
Sisir

Das Problem

Wenn die Tabelle bereits vorhanden ist, versucht Ihr Code weiterhin, die folgenden Abfragen auszuführen:

1) ALTER TABLE wp_voicemail_call CHANGE COLUMN user_id user_id BIGINT(9) UNSIGNED NOT NULL
2) ALTER TABLE wp_voicemail_call CHANGE COLUMN call_id call_id BIGINT(9) UNSIGNED NOT NULL
3) ALTER TABLE wp_voicemail_call CHANGE COLUMN opened opened BOOL DEFAULT 0 NOT NULL
4) ALTER TABLE wp_voicemail_call ADD 
5) ALTER TABLE wp_voicemail_call ADD PRIMARY KEY (user_id, call_id)

Beachten Sie, dass diese Abfrage:

ALTER TABLE wp_voicemail_call ADD PRIMARY KEY (user_id, call_id)

versucht, einen anderen Primärschlüssel hinzuzufügen, der bereits definiert ist, und wir können nur einen von diesen haben. Also der Fehler.

Diese Abfrage:

ALTER TABLE wp_voicemail_call ADD

kommt aus der Leerzeile über der PRIMARY KEY-Zeile.

In der Funktion dbDelta() gibt es diesen Teil der die Primärteile aufheben sollte:

foreach ( $index_strings as $index_string ) {
    if ( ! ( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
        unset( $indices[ $aindex ] );
        break
     }
}

aber die Array-Suche gibt aus irgendeinem Grund immer false zurück.

Ich habe tiefer gegraben und in deinem Fall ist das $indices-Array:

Array
(
    [0] => 
    [1] => PRIMARY KEY  (user_id, call_id)
)

aber das $index_strings array ist

Array
(
    [0] => PRIMARY KEY  (user_id,call_id)
    [1] => PRIMARY KEY  (user_id,call_id)
)

So können wir die Nichtübereinstimmung sehen:

PRIMARY KEY  (user_id,call_id) 

versus

PRIMARY KEY  (user_id, call_id)

... ein einzelnes Leerzeichen !!

Die vorgeschlagene Lösung

Also, wenn wir die zusätzliche leere Zeile und den zusätzlichen Raum entfernen:

$sql = "CREATE TABLE {$wpdb->prefix}voicemail_call (
    user_id BIGINT(9) UNSIGNED NOT NULL,
    call_id BIGINT(9) UNSIGNED NOT NULL,
    opened BOOL DEFAULT 0 NOT NULL,
    PRIMARY KEY  (user_id,call_id)
);";

dann sollten wir diese Abfragen nur mit dbDelta() ausführen lassen:

1) ALTER TABLE wp_voicemail_call CHANGE COLUMN user_id user_id BIGINT(9) UNSIGNED NOT NULL
2) ALTER TABLE wp_voicemail_call CHANGE COLUMN call_id call_id BIGINT(9) UNSIGNED NOT NULL
3) ALTER TABLE wp_voicemail_call CHANGE COLUMN opened opened BOOL DEFAULT 0 NOT NULL

wenn die Tabelle bereits existiert.

5
birgire