2013-08-11 3 views
1

J'ai une table nommée 1 avec ces enregistrements:requête SQL ne marche pas retourner les lignes correctes

ID one   two     three 
1: 1AijS0 - 6Aݨ⻈㗨㙡㙡⻑S0S0S0S0S0S0 - 1AijS0 
2: 1AijS0 - 6Aࡀ㐠㗨㙡㙡⻑S0S0S0S0S0S0 - 1AijS0 

(notez que l'un et trois colonnes des deux enregistrements ont 5 caractères et sont identiques et deux colonnes a 20 caractères, mais sont pas même)

ici, j'ai des problèmes:

quand j'utiliser cette commande supprimer (peu importe où), les deux lignes sont supprimées (bien que la ligne correcte est la deuxième):

DELETE FROM [1] WHERE two='6Aࡀ㐠㗨㙡㙡⻑S0S0S0S0S0S0' AND three='1AijS0' AND one='1AijS0' 

Je n'ai pas vu le deuxième problème dans d'autres exemples d'enregistrements.

+0

est-ce un jeu de caractères utf8? essayez d'utiliser 'COLLATE' avec votre querry. [Utilisation de COLLATE dans les instructions SQL] (http://dev.mysql.com/doc/refman/5.0/en/charset-collate.html) – bansi

+0

Comment puis-je l'utiliser? – Feri

+5

lorsque vous utilisez unicode vous devez préfixer votre chaîne avec N par exemple: O WH deux = N'6Aࡀ S0S0S0S0S0S0 ' – VahidNaderi

Répondre

1

Si les colonnes sont nvarchar, vous devez utiliser préfixes N pour indiquer littéraux nvarchar ...

SELECT * FROM [1] WHERE two=N'6Aݨ⻈㗨㙡㙡⻑... 

Mais mieux encore: paramètres d'utilisation, ce qui évite ce problème et permet également d'éviter l'injection SQL en même temps :

SELECT * FROM [1] WHERE [email protected] 

et il suffit d'ajouter le paramètre:

string two = ... // the value you want 
cmd.Parameters.AddWithValue("two", two); 
+0

J'ai essayé le préfixe N mais il a une erreur de syntaxe et n'a pas compris la deuxième manière – Feri

+0

@Feri quoi exactement l'erreur de syntaxe dit? Si (comme dans les commentaires), il s'agit d'un serveur sql, alors les deux sont parfaitement bien. La 2ème approche (les paramètres) devrait en fait être la façon dont vous écrivez la plupart de vos opérations SQL. Si ce n'est pas le cas, alors vous devez vraiment corriger cela! –

+0

Le premier problème est résolu maintenant mais le second existe. – Feri

0

le résultat o f une comparaison de chaînes dépend du classement d'un jeu de caractères. Par défaut, il s'agit du classement spécifié lors de l'installation de l'instance de serveur, mais les classements peuvent également être spécifiés aux niveaux de la base de données et de la colonne de table. Ils peuvent également être spécifiés dans la requête. Les collations peuvent s'appliquer aux comparaisons et aux chaînes individuelles, et il existe de nombreuses règles concernant la compatibilité des collations.

Les chaînes de votre exemple sont considérées comme égales dans le classement utilisé lors de l'exécution de la requête.

Il n'y a pas de réponse facile à la question de savoir si vous avez des chaînes dans plusieurs langues. Si vous souhaitez que les chaînes qui semblent différentes soient considérées comme inégales, vous pouvez essayer un classement binaire. Toutefois, si vous comparez des chaînes à l'aide d'un classement différent du classement système ou du classement applicable car il a été spécifié pour la base de données ou la colonne de la table, le processeur de requêtes risque de ne pas pouvoir utiliser les index. lentement.

L'interprétation des chaînes fournies par l'utilisateur peut également dépendre des paramètres régionaux du système d'exploitation, et les résultats peuvent changer en fonction de l'utilisation du N qui indique Unicode.

Voici une démonstration de la façon dont les chaînes dans votre exemple pourraient être considérés comme égaux sous certains classements et inégale sous d'autres:

with t(a,b) as (
    select 
    N'6Aࡀ㐠㗨㙡㙡⻑S0S0S0S0S0S0', 
    N'6Aݨ⻈㗨㙡㙡⻑S0S0S0S0S0S0' 
) 
    select 
    'Japanese_CI_AI' as Collation, 
    case when a=b collate Japanese_CI_AI then 'Equal' else 'Not Equal' end as Result, 
    a, b 
    from t 
    union all 
    select 
    'Latin1_General_100_CS_AI' as Collation, 
    case when a=b collate Latin1_General_100_CS_AI then 'Equal' else 'Not Equal' end as Result, 
    a, b 
    from t 
    union all 
    select 
    'Arabic_100_CI_AS' as Collation, 
    case when a=b collate Arabic_100_CI_AS then 'Equal' else 'Not Equal' end as Result, 
    a, b 
    from t 
    union all 
    select 
    'SQL_Latin1_General_CP1_CI_AI' as Collation, 
    case when a=b collate SQL_Latin1_General_CP1_CI_AI then 'Equal' else 'Not Equal' end as Result, 
    a, b 
    from t 

union all select « Latin1_General_BIN » comme Collation, cas où a = b assembler Latin1_General_BIN puis 'Equal' sinon 'Pas égal' comme résultat, a, b de t

+0

Merci de votre aide mais je n'ai pas bien compris vos codes. Pouvez-vous les expliquer? – Feri

+0

Ceci est juste un exemple pour montrer que le classement peut affecter le résultat de la comparaison des chaînes avec =. Vous devriez faire quelques lectures sur les classements de caractères (recherchez COLLATE dans la documentation en ligne). Si vous avez une question spécifique sur une partie de cet exemple. Ce n'est pas pratique d'essayer d'expliquer le tout sans savoir ce qui vous dérange. –

Questions connexes