Je veux écrire une procédure stockée qui fonctionne comme ceci:
IF EXISTS (SELECT * from T where T.A = @a and T.B = @b) THEN SELECT * from T where T.A = @a and T.B = @b ELSE SELECT * from T where T.A = @a and T.B IS NULL
7 Réponses :
Cela devrait éviter l'accès de la table supplémentaire pour la vérification de l'existence. Je ne suis pas sûr s'il y a une manière de Néater.
Je pense que c'est le meilleur interprète, mais votre application doit examiner le deuxième résultat si le premier résultat est vide.
Je n'ai pas pu utiliser cela à cause des multiples résultats de résultats, mais c'était ce que je cherchais.
edit strong> La réponse a été modifiée après la modification de la question. CREATE PROCEDURE myconditionalsp
@a <type>,
@b <type>
AS
SELECT * from T
where
-- the second condition is true AND the first condition is false
(((T.A = @a) and (T.B IS NULL)) AND NOT ((T.A = @a) and (T.B = @b)))
OR
-- the first condition is true (regardless what is the second condition)
((T.A = @a) and (T.B = @b))
GO
Pour que cela fonctionne de la même manière, la partie "et non" aurait besoin d'être "et n'existe pas (......)
Vous pouvez également le faire dans une requête:
SELECT * from T where (T.A = @a and T.B = @b) OR ( 0=(SELECT COUNT(*) T1 where (T1.A = @a and T1.B = @b) ) AND T.A = @a and T.b IS NULL)
Je pense que vous pouvez le faire avec une variable de table, ce qui devrait éviter le problème des deux Resulats. Quelque chose comme:
Il y a une surcharge avec cette approche cependant dans la création de la variable de table, en l'insérant, puis en choisissant à partir de celui-ci pouvant dépasser tout avantage potentiel d'éviter le chèque. Je commence à penser que l'approche de la question ne peut pas vraiment être améliorée.
Pourquoi ne pouvez-vous pas faire cela dans une seule requête:
Select ... From T Where T.A = @a And T.B = @b Union All (Select ... From T Where T.A = @a And T.B Is Null Except Select ... From T Where T.A = @a And T.B = @b)
Demande unique Oui, mais pareil ou pire plan d'exécution.
@BC - Pas nécessairement. Cela pourrait gérer le problème du paramètre reniflant mieux que de la déclaration IF.
Je ne le sais pas si aide à toutes les performances, mais vous pourriez essayer une fonction valorisée de table: mais je doute que cela aide. P> En général, je collerais avec votre approche initiale. C'est le plus simple et le plus propre. Et le cache et un bon indice devraient s'occuper des performances. P> S'il y avait des problèmes de performance réels ici, je recettes et examinez cette conception de la base de données. Pourquoi as-tu des nulls là-bas? Pourquoi essayez-vous deux filtres? Peut-il être modélisé différemment? Sinon, peut-être une petite dénoralisation? P> p>
Essayez ceci, si les premières lignes de retour SELECT, il renvoie si le premier échoue que la sélection suivante renvoie ou enfin la dernière sélection:
IF EXISTS(SELECT * FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='BERJGS') BEGIN SELECT * FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='BERJGS' PRINT 'TOLA' RETURN END ELSE BEGIN SELECT * FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='6CHOPS' IF @@ROWCOUNT > 0 RETURN --RETURN END SELECT * FROM Customers where Customers.CustomerID='FRANK'
Et votre question ou votre problème est?!?!?!?? Vous semblez avoir une approche - ne fonctionne pas, ni quel est le problème?
Si c'est SQL Server 2000, c'est la meilleure approche que je connaisse mais +1 parce que j'aimerais savoir s'il y a une autre façon!
Je crois qu'il demande s'il existe un moyen plus efficace de le faire. Il y a.
Dans SQL 2005 et que vous pourriez probablement faire des choses goofy avec des CTES pour que cela ressemble à une requête, mais cela finira probablement à lire et à traiter la même quantité de données que si le si existe ... Alors ... Ause versions .
@PLIPHIP - Je viens d'essayer cela mais je ne pouvais pas faire
et n'existe pas (Select * des résultats) code> au 2ème niveau car j'ai obtenu l'erreur
Les références récursives ne sont pas autorisées dans les sous-requêtes. Code>