2010-10-11 8 views
2

Dans mon code C#, je dois faire une requête SQL comme ceci:requête SQL Server avec la valeur null

context.ExecuteStoreQuery("SELECT * FROM MyTable WHERE Field0 = {0} AND 
    Field1 = {1}", field0, field1) 

Lorsque field1 = null dans C# et NULL dans la base de cette requête ne fonctionne pas. (Je dois utiliser une syntaxe différente avec IS NULL)

Comment puis-je corriger ceci sans faire de si (en réalité, j'ai 10 champs ...)?

+3

Looks mûre pour injection SQL. http://xkcd.com/327/ – Oded

+2

@Oded: 'ObjectContext.ExecuteStoreQuery' n'est pas la même chose que' string.Format', malgré la similitude de la syntaxe. 'ObjectContext.ExecuteStoreQuery' paramètre la requête automatiquement. –

+1

@Adam Robinson - Merci pour l'info. Je vais laisser mon commentaire plus tôt, donc vos informations seront dans le contexte :) – Oded

Répondre

4

Par défaut, le serveur SQL ne vous permet pas de comparer une valeur à null. Toutes les comparaisons se résolvent en false, même celles qui sont logiquement opposées. En d'autres termes, vous pouvez faire:

where field = 1 et where field <> 1. Si field est null, les deux résolvent logiquement à false.

Dans tous les cas, vous avez besoin d'un contrôle explicite pour null dans votre requête: bien

context.ExecuteStoreQuery(@"SELECT * FROM MyTable WHERE 
    (Field0 = {0} or (Field0 is null and {0} is null)) AND 
    (Field1 = {1} or (Field1 is null and {0} is null))", field0, field1) 
+0

'AND [_TYPE] = CAS LORSQUE NULL EST NULL ALORS [_TYPE] ELSE @TYPE END' cela fonctionne correctement dans SQL Server 2008 et cela me rend fou, car il ne peut pas être utilisé dans la chaîne C# SQL. – bonCodigo

0

Vous pouvez utiliser la variante courte de l'instruction if. Je ne pense pas que vous pouvez gérer votre problème sans une instruction if. Exemple:

String.Format("SELECT * FROM MyTable WHERE Field0 {0} ", value==null ? "IS NULL" : String.Format("= {0}", value)) 

Il est également possible de paramétrer la requête en utilisant "@ParameterName"

context.ExecuteStoreQuery<ProductionUnit>(
    String.Format("SELECT * FROM MyTable WHERE Field0 {0} @Parameter1", 
    value==null ? "IS", "="), new SqlParameter("@Parameter1", value)); 

Cordialement

+0

Interestign approche. {1} peut encore être paramétré bien sûr – gbn

+0

Vous aurez NullReferenceException car String.Format appellera value.ToString même si la première condition retournera true. – cement

+0

@cement: Vous pouvez passer 'null' à' string.Format', bien que cette conception ne fonctionne pas dans ce scénario particulier. 'ObjectContext.ExecuteStoreQuery' (qui est ce que l'utilisateur utilise) n'est pas seulement une fonction de formatage de chaîne, car il paramètre automatiquement la requête en utilisant les valeurs fournies. Cette approche ne produira pas de SQL valide. –

0
public string appendCondition(String sqlQuery, String field, Object value) 
{ 
string resultQuery = sqlQuery + " " + value == null ? " IS NULL " : "=" + value.ToString(); 
return resultQuery; 
} 

espère que vous pouvez ajouter une logique simple d'ajouter "WHERE" ou "ET" par vous-même.

0

, la première chose que je voudrais faire est de supprimer la sélection *. MAL!

la deuxième chose que je ferais est de faire une procédure stockée.

create procedure dbo.MyTableSelect 
    @field0 int, 
    @field1 int=null 
as 
begin 

    select 
     * 
    from MyTable 
    where [email protected] 
     and (@field1 is null or [email protected]) 



end 

vous pouvez changer votre code à ce

context.ExecuteStoreQuery("exec dbo.MyTableSelect @field0={0}, @field1 = {1}", field0, field1)