6
votes

Procédure stockée avec résultats conditionnels

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


5 commentaires

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) 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.


7 Réponses :


5
votes

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. XXX


2 commentaires

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.



-2
votes

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


1 commentaires

Pour que cela fonctionne de la même manière, la partie "et non" aurait besoin d'être "et n'existe pas (......)



0
votes

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)


0 commentaires

1
votes

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: xxx


1 commentaires

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.



1
votes

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)


2 commentaires

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.



0
votes

Je ne le sais pas si aide à toutes les performances, mais vous pourriez essayer une fonction valorisée de table: xxx

mais je doute que cela aide.

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.

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?


0 commentaires

0
votes

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'


0 commentaires