2012-09-05 3 views
0

Je rencontre des problèmes avec un peu de code destiné à trouver des doublons d'un nom avec la plate-forme. Cela sera également adapté pour trouver des identifiants uniques plus tard. Par exemple, s'il y a un serveur nommé "Apple" sur la Xbox et que vous essayez d'insérer un enregistrement avec le nom "Apple" avec la même plate-forme, il le rejettera. Cependant, une autre plate-forme avec le même nom est autorisée, comme "Apple" avec PS3.Recherche d'entrées en double avec PDO

J'ai essayé de trouver des idées et de chercher des réponses, mais je ne sais pas du tout quelle est la meilleure façon de vérifier les doublons.

Jusqu'à présent, c'est ce que j'ai:

$nameDuplicate_sql = $db->prepare("SELECT * FROM `servers` WHERE name=':name' AND platform=':platform'"); 
$nameDuplicate_sql->bindValue(':name', $name); 
$nameDuplicate_sql->bindValue(':platform', $platform); 
$nameDuplicate_sql->execute(); 

J'ai essayé un tas de différentes solutions, certains d'ici, d'autres de manuel, etc Aucun du PHP semble fonctionner bien.

J'essaie de coller avec PDO, cependant, c'est un exemple où je ne peux pas savoir où tourner. Si c'était dans mysql_ *, je pourrais probablement utiliser mysql_affected_rows, mais avec PDO, je n'ai aucune idée. rowCount semble prometteur, mais il renvoie toujours 0 car il ne s'agit pas d'une instruction INSERT, UPDATE ou DELETE.

Oh, et j'ai essayé l'instruction SQL dans phpMyAdmin et ça marche; Je l'ai essayé avec un nom simple/plate-forme et il a trouvé des lignes correctement.

Si quelqu'un peut m'aider ici, je l'apprécierais.

Répondre

2

Pour la plupart des bases de données, PDOStatement :: rowCount() ne retourne pas le nombre de lignes affectées par une instruction SELECT. À la place, utilisez PDO :: query() pour émettre une instruction SELECT COUNT (*) avec les mêmes prédicats que votre instruction SELECT, puis utilisez PDOStatement :: fetchColumn() pour récupérer le nombre de lignes renvoyées. Votre application peut alors effectuer l'action correcte.

+0

Mes seuls scrupules avec ceci est que je devrais y échapper, c'est pourquoi je préfère me pencher vers une déclaration préparée. Serait-il possible d'utiliser une instruction SELECT COUNT (*) avec une instruction préparée au lieu d'une requête? Je ne me fais vraiment pas confiance en m'échappant. – Battleroid

+0

En fait, j'ai essayé cela avec une déclaration préparée et cela fonctionne. J'ai utilisé fetchColumn avec SELECT COUNT (*) comme vous l'avez mentionné et il retourne de manière fiable les lignes qui correspondent à la condition. – Battleroid

1

Supprimez les guillemets simples de votre requête sur les jetons de paramètres ... ils seront indiqués une fois qu'ils sont liés ... cela fait partie de la raison d'une instruction préparée.

$nameDuplicate_sql = $db->prepare("SELECT * FROM `servers` WHERE name= :name AND platform= :platform"); 
+0

Je n'étais pas au courant. Ça ira. – Battleroid

+0

Vous devriez également utiliser une requête de comptage ici comme Sel suggéré. – prodigitalson

2

Au lieu de vérifier les doublons, pourquoi ne pas l'appliquer directement sur la table de base de données? Créer une clé composite qui interdira les entrées effectuées si elles sont déjà là?

CREATE TABLE servers (
    serverName varchar(50), 
    platform varchar(50), 
    PRIMARY KEY (serverName, platform) 
) 

De cette façon, vous serez jamais obtenir des doublons, et il vous permet également d'utiliser la syntaxe mysql insert... on duplicate key update... qui sonne comme il pourrait être assez pratique pour vous.

Si vous avez déjà une clé primaire sur ou vous ne voulez pas faire une nouvelle table, vous pouvez utiliser les éléments suivants:

ALTER TABLE servers DROP PRIMARY KEY, ADD PRIMARY KEY(serverName, platform); 

Edit: Une clé primaire est soit une seule ligne ou une nombre de lignes ont pour avoir des données uniques. Une seule ligne ne peut pas avoir la même valeur deux fois, mais une clé composite (ce que je suggère ici) signifie qu'entre les deux colonnes, les mêmes données ne peuvent pas apparaître.Dans ce cas, ce que vous voulez faire, ajouter un nom de serveur et l'associer à une plate-forme - la table vous permettra d'ajouter autant de lignes contenant le même nom de serveur - tant que chacun a un plate-forme unique associée à elle - et vice versa, vous pouvez avoir une plate-forme répertoriée autant de fois que vous le souhaitez, tant que tous les noms de serveur sont uniques.

Si vous essayez d'insérer un enregistrement où la même combinaison serveur/plate-forme existe, la base de données ne vous laissera tout simplement pas le faire. Il y a un autre avantage d'or cependant. En raison de cette contrainte de clé - mysql permet d'utiliser un type de requête particulier. C'est la syntaxe insert... on duplicate key update. Cela signifie que si vous essayez d'insérer deux fois les mêmes données (par exemple, la base de données dit non), vous pouvez l'attraper et mettre à jour la ligne que vous avez déjà dans le tableau. Par exemple:

Vous avez une ligne avec serverName=Fluffeh et il est sur platform=Boosh mais vous ne le savez pas pour le moment, vous essayez donc d'insérer un enregistrement avec l'intention de mettre à jour l'adresse IP du serveur.

Normalement, vous devriez simplement écrire quelque chose comme ceci:

insert into servers (serverName, platform, IPAddress) 
values ('$serverName', '$platform', '$IPAddy') 

Mais avec une belle clé primaire identifié, vous pouvez le faire:

insert into servers (serverName, platform, IPAddress) 
values ('$serverName', '$platform', '$IPAddy') 
on duplicate key update set IPAddress='$IPAddy'; 

La deuxième requête d'insérer la ligne avec toutes les données si ça n'existe pas déjà. Si c'est le cas, Bam! il mettra à jour l'adresse IP du serveur qui était votre intention tout le long.

+0

Je n'ai jamais rien vu de pareil. Comment cela fonctionne-t-il exactement? – Battleroid

+0

Eh bien, je ne voudrais pas en faire la clé primaire .. Je voudrais utiliser une deuxième clé unique. – prodigitalson

+0

@CaseyWeed Voir (long) éditer :) – Fluffeh