2010-01-16 3 views
-1

J'ai un script:MySQL COMME question

$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote 
WHERE tousers LIKE '%$userinfo[username]%' "); 

Et le contenu de la table "tousers" de la base de données:

Test 
Example 
User 

Ce scénario semble fonctionner bien

Cependant, s'il y a un utilisateur appelé "Test2", il affichera également le contenu qui a "Test2" dans la base de données où $ userinfo [nom d'utilisateur] est juste "Test"

Y at-il un moyen de résoudre ce problème? Par exemple (ce n'est qu'un exemple, cela ne me dérange pas si vous donnez un autre moyen) faites en sorte qu'il recherche des lignes entières?

EDIT: Je ne pense pas que quiconque comprend, la table « tousers » contient plusieurs valeurs (par ligne) séparées pas seulement une, je veux qu'il recherche chaque ligne (ou tout ce qui fonctionne similaire), pas rangée

+1

Etes-vous sûr que vous voulez les caractères génériques, plutôt que de simplement faire correspondre la valeur avec le contenu entier du champ? –

+2

Vous devriez vraiment échapper à ce nom d'utilisateur. De préférence avant les petites tables de bobby http://xkcd.com/327/ –

+0

Ok, je suis officiellement confus. Voulez-vous dire que vous voulez regarder dans plusieurs domaines? Je pense que vous devez publier un certain contenu de votre table, et quelques exemples concrets de ce que vous voulez rechercher, parce que sinon, nous ne faisons que parler à contre-courant. – Martha

Répondre

2

La condition

tousers LIKE '%Test%' 

signifie que touser contient "Test" à un moment donné, il est donc vrai pour "Test", "MyTest", "Test3" "MyTest3", et ainsi de suite.

Si vous voulez seulement correspondre à l'utilisateur actuel, essayez

... WHERE tousers = '$userinfo[username]' 

EDIT Si vous voulez vraiment stocker plusieurs noms dans une colonne (séparés par des sauts de ligne), vous pouvez utiliser un modèle de REGEXP comme

WHERE tousers REGEXP '(^|\\n)($userinfo[username])($|\\n)' 

Sachez vous assurer que $userinfo[username] ne contient pas de caractères comme expression régulière (de '$', '^', '|'., '(', etc.) aussi (comme mentionné dans le commentaires ci-dessus) cette solution est suboptim al en termes de sécurité/performance/etc: Il serait préférable de modéliser un 1: n-relation entre la table friendnote et une table de friendnotes_user ...

+0

Veuillez consulter l'avis de modification sur la question – Ryan

0

D'après ce que je comprends, vous devez simplement utiliser comparaison stricte:

where tousers = 'whatever' 

C'est parce que tousers like %whatever% correspond à une ligne, dans lequel le champ tousers a « tout » ne importe où dans son contenu, il correspond à « tout ',' 123whatever ',' any321 'et' 123whatever321 '. J'espère que vous avez l'idée.

+0

Mais le champ "tousers" contient plusieurs valeurs, et le script doit rechercher dans le champ – Ryan

0

Vous souhaitez uniquement rechercher les correspondances de noms exactes? Dans ce cas, il suffit d'utiliser un = et enlever les % wildcards:

$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote 
WHERE tousers = '$userinfo[username]' "); 
+0

Veuillez consulter l'avis de modification sur la question – Ryan

1

Cela fonctionnera si vous supprimez les % signes, qui sont ce qui permettent de correspondance de motif.

$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote 
WHERE tousers LIKE '$userinfo[username]' "); 

Mais le consensus semble être que l'utilisation d'égales sera plus rapide. See https://stackoverflow.com/questions/543580/equals-vs-like.

Donc, dans ce cas, passez à

$friendnotes = mysql_query("SELECT nid,user,subject,message FROM friendnote 
WHERE tousers = '$userinfo[username]' "); 

Modifier - au sujet de votre édition, ce n'est pas un design vraiment bon. Si un utilisateur peut avoir plusieurs "tousers" (c'est-à-dire une relation un-à-plusieurs), cela doit être représenté comme une table distincte tousers, où chaque ligne représente un "touser" et possède une clé étrangère sur l'ID de l'utilisateur avec le tableau friendnote. Mais si vous ne pouvez absolument pas changer votre conception, vous voudrez peut-être correspondre à ceci:

WHERE tousers LIKE '%$userinfo[username]\n%' ");

assurant qu'il ya un saut de ligne immédiatement après le nom d'utilisateur.

+0

Veuillez consulter l'avis de modification sur la question – Ryan

1

Ok, donc il semble que le champ tousers peut contenir des valeurs comme 'stuff test option any' et 'foo test2 quelque chose bla bla', et vous voulez faire correspondre le premier mais pas le second. Dans ce cas, vous devez inclure les délimiteurs autour de votre terme de recherche. En supposant que le terme de recherche aura toujours un espace avant et un espace ou une virgule après, vous pouvez faire quelque chose comme: cependant,

... WHERE tousers LIKE '%[ ]$userinfo[username][ ,]%' 

Cela rencontrera des problèmes, si votre terme de recherche peut se produire au début de la champ (pas de caractère espace avant) ou à la fin du champ (pas de délimiteur après). Dans ce cas, vous devrez peut-être avoir plusieurs clauses LIKE.

0

Ceci est un cas d'utilisation parfait pour l'opérateur MySQL REGEXP.