2009-10-20 13 views
2

J'utilise Visual Web Developer 2008 EE à l'aide d'un jeu de données (.xsd) pour développer une application de facturation et j'ai de la difficulté à créer une requête de recherche personnalisée. J'ai un ObjectDataSource qui attend 4 ControlParameters, comme ceci:ObjectDataSource et les paramètres null

<asp:ObjectDataSource ID="odsInvoices" runat="server" SelectMethod="getInvoices" TypeName="bllInvoice"> 
    <SelectParameters>    
     <asp:ControlParameter ControlID="drpProjectsFilter" Type="Int32" Name="intProject" PropertyName="SelectedValue" ConvertEmptyStringToNull="True" />  
     <asp:ControlParameter ControlID="drpMonthsFilter" Type="Int32" Name="intMonth" PropertyName="SelectedValue" ConvertEmptyStringToNull="True" /> 
     <asp:ControlParameter ControlID="drpYearFilter" Type="Int32" Name="intYear" PropertyName="SelectedValue" ConvertEmptyStringToNull="True" /> 
     <asp:ControlParameter ControlID="drpStatusFilter" Type="Int32" Name="intStatus" PropertyName="SelectedValue" ConvertEmptyStringToNull="True" /> 
    </SelectParameters> 

Pour chacun de ces contrôles (listes déroulantes) J'ai une valeur par défaut de « » (= chaîne vide) et je l'ai ajouté l'option ConvertEmptyStringToNull = » True "pour chaque paramètre. La requête qui est derrière le ObjectDataSource est celui-ci:

SELECT ... FROM ... 
WHERE (YEAR(invoices.invoice_date) = COALESCE (@year, YEAR(invoices.invoice_date))) 
AND (invoices.fk_project_id = COALESCE (@projectID, invoices.fk_project_id)) 
AND (MONTH(invoices.invoice_date) = COALESCE (@month, MONTH(invoices.invoice_date))) 
AND (invoices.invoice_status = COALESCE (@statusID, invoices.invoice_status)) 

En utilisant COALESCE, je suis essentiellement dire d'ignorer l'un des 4 paramètres si elles sont nulles et de retourner toutes les lignes.

Le problème est que cette requête ne renvoie aucune ligne, à moins que je ne spécifie une valeur pour chacun des 4 paramètres, essentiellement démystifier le but entier de cette recherche personnalisée.

Vous ne savez pas pourquoi cela ne fonctionne pas? Merci d'avance!

Répondre

1

De la documentation MSSQL:

ISNULL et COALESCE bien équivalent, peuvent se comporter différemment. Une expression impliquant ISNULL avec des paramètres non NULL est considérée comme NOT NULL, tandis que les expressions impliquant COALESCE avec des paramètres non NULL sont considérées comme NULL.

Donc, essayez de changer votre requête pour ressembler à ceci:

select ... 
    from ... 
where year(invoices.invoice_date) = isnull(@year, year(invoices.invoice_date)) 
    and invoices.fk_project_id  = isnull(@projectID, invoices.fk_project_id) 
    and month(invoices.invoice_date) = isnull(@month, month(invoices.invoice_date)) 
    and invoices.invoice_status  = isnull(@statusID, invoices.invoice_status) 

Si cela ne fonctionne pas, utilisez SQL Profiler pour vérifier exactement ce qui est passé à votre SELECT quand il est invoqué.

+0

Merci Ian, mais j'ai d'abord essayé avec ISNULL et il ne fonctionnait pas. Aussi, je veux éviter d'utiliser ISNULL car il est seulement supporté par T-SQL, et qui sait que nous pourrions changer notre fournisseur de BD à l'avenir. –

+0

Dans ce cas, je ne peux que suggérer SQL Profiler :). J'ai rencontré des problèmes avec 'ConvertEmptyStringToNull' étant ignorés dans Mono, mais je doute que cela s'applique à votre situation. –

+0

Jetez un oeil à l'SQL dans ma réponse à http://stackoverflow.com/questions/1493458/search-based-on-matched-criteria/1493643#1493643 qui je pense fera ce que vous voulez et peut-être un peu plus portable. – PhilPursglove

1

J'ai réussi à résoudre mon propre problème. Comme il se trouve, les ControlParameters ne suis pas retourné NULL (comme dans une valeur DBNull), mais le nombre réel 0. J'ai adapté mon instruction SQL à ce qui suit:

select ... from ... 
where ((@year=0) OR (year(invoices.invoice_date)[email protected])) 
and ((@projectID=0) OR ([email protected])) 
and ((@month=0) OR (month(invoices.invoice_date)[email protected])) 
and ((@statusID=0) OR ([email protected])) 

De cette façon, si un ControlParameter a une valeur de 0, il retournera toujours toutes les lignes. Espérons que cela peut aider quelqu'un.

Cordialement, Stijn