web-dev-qa-db-fra.com

Comment définir des clés composites avec dbDelta ()

Je reçois une erreur en essayant de créer une table avec dbDelta() et une clé primaire composite. Le sql est assez simple.

$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);

Cela montre une erreur

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

Est-ce que je me trompe? Comment définir correctement la clé primaire composite avec dbDelta?

Remarque: Bien l'erreur est affichée, mais la table est toujours créée et les deux colonnes sont définies comme clé primaire.

4
Sisir

Le problème

Si la table existe déjà, votre code essaiera quand même d'exécuter les requêtes suivantes:

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)

Notez que cette requête:

ALTER TABLE wp_voicemail_call ADD PRIMARY KEY (user_id, call_id)

tente d'ajouter une autre clé primaire déjà définie et nous ne pouvons en avoir qu'une. Donc l'erreur.

Cette requête:

ALTER TABLE wp_voicemail_call ADD

vient de la ligne ligne vide au-dessus de la ligne PRIMARY KEY.

Dans la fonction dbDelta(), il y a cette partie qui devrait désactiver les parties principales:

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

mais la recherche de tableau retourne toujours faux dans votre cas pour une raison quelconque.

J'ai creusé plus profondément et dans votre cas, le tableau $indices est:

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

mais le tableau $index_strings est

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

Donc, nous pouvons voir l'inadéquation:

PRIMARY KEY  (user_id,call_id) 

versus

PRIMARY KEY  (user_id, call_id)

... un seul espace !!

La solution suggérée

Donc, si nous supprimons la ligne vide supplémentaire et l'espace supplémentaire:

$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)
);";

alors nous devrions seulement faire en sorte que ces requêtes s'exécutent avec dbDelta():

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

quand la table existe déjà.

5
birgire