2014-08-27 3 views
0

Je crée une requête qui vérifie que certaines contraintes sont satisfaites. Voici une version semi-travail en ce moment:Renvoie le résultat de la requête même si la clause WHERE n'est pas remplie

SELECT CASE 
      WHEN TaskId IS NULL THEN 0 
      ELSE 1 
     END AS TaskExists, 
     CASE 
      WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
      WHEN IsDownTask = 1 THEN 1 
      ELSE 0 
     END AS PressReady, 
     CASE 
      WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
      ELSE 0 
     END AS DownTaskAssignedToDifferentMachine 
FROM Task T 
WHERE TaskId = 555555 

Cela fonctionne bien quand TaskId existe dans la table Task, mais je dois aussi retourner des valeurs si cette tâche n'existe pas (d'où le champ TaskExists).

Pour une requête sur une tâche inexistante, je vous attendez à retourner

  • TaskExists 0
  • PressReady 0
  • DownTaskAssignedToDisfferentMachine 0

Comment puis-je modifier ma requête pour retourner cela même quand il n'y a pas TaskId existe?

+0

Lorsque le 'taskId' n'existe pas dans cette table où d'autre existe-t-il? –

+0

Cela pourrait être fait en utilisant peut-être une instruction SQL assez moche. Si j'étais vous, je laisserais juste le SQL comme ceci et implémenterais un [Null Object] (http://en.wikipedia.org/wiki/Null_Object_pattern) sur le côté C# qui a les attributs que vous avez énumérés. J'utiliserais l'objet nul au cas où le SQL ne retournerait aucun résultat – GolfWolf

+0

Est-ce que TaskId est unique dans cette table? – Bulat

Répondre

14

Si vous voulez retourner ces valeurs enveloppent juste chaque colonne avec un SUM et un ISNULL:

SELECT ISNULL(SUM(CASE 
     WHEN TaskId IS NULL THEN 0 
     ELSE 1 
    END), 0) AS TaskExists, 
    ISNULL(SUM(CASE 
     WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
     WHEN IsDownTask = 1 THEN 1 
     ELSE 0 
    END), 0) AS PressReady, 
    ISNULL(SUM(CASE 
     WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
     ELSE 0 
    END), 0) AS DownTaskAssignedToDifferentMachine  
+1

Je voudrais juste utiliser 'count (TaskId)' pour 'TaskExists'. –

+0

Count fonctionnerait aussi et nous permettrait d'éliminer l'expression de cas aussi. Bonne idée. –

+0

Oui, cela fonctionne comme je le veux. J'ai suggéré une modification pour ajouter des vérifications 'ISNULL' aux deux derniers champs. Sinon, ils renvoient 'NULL' et je veux éviter d'avoir à retourner des entiers NULL de la base de données. – Killnine

-1

S'il vous plaît essayez le code ci-dessous. Je n'ai pas testé.

SELECT CASE 
       WHEN TaskId IS NULL THEN 0 
       ELSE 1 
      END AS TaskExists, 
      CASE 
       WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
       WHEN IsDownTask = 1 THEN 1 
       ELSE 0 
      END AS PressReady, 
      CASE 
       WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
       ELSE 0 
      END AS DownTaskAssignedToDifferentMachine 
    FROM Task T 
    WHERE 1= case when TaskId = 555555 then 1 
    else 0 end 
+0

Suggéré une modification à ceci: votre ELSE était un 'o' au lieu de zéro. Il est bon que vous l'ayez signalé comme non testé, mais à l'avenir, il pourrait être utile de prendre le temps de tester vos réponses avant de les poster. Une réponse de meilleure qualité, même avec quelques minutes de retard, est de loin préférable. problème. – AHiggins

1

Vous pouvez essayer quelque chose comme ceci:

DECLARE @task INT 
SET @task = 555555 

SELECT CASE 
      WHEN TaskId IS NULL THEN 0 
      ELSE 1 
     END AS TaskExists, 
     CASE 
      WHEN IsDownTask = 0 AND TaskStatus = 63 THEN 1 
      WHEN IsDownTask = 1 THEN 1 
      ELSE 0 
     END AS PressReady, 
     CASE 
      WHEN IsDownTask = 1 AND MachineId <> 2710 THEN 1 
      ELSE 0 
     END AS DownTaskAssignedToDifferentMachine 
FROM Task T 
WHERE TaskId = @task 
UNION ALL 
SELECT 0 TaskExists, 0 PressReady, 0 DownTaskAssignedToDifferentMachine 
WHERE NOT EXISTS (SELECT * FROM Task WHERE TaskId = @task) 
1

Si elle doit être dans une requête, plutôt que dans le code, puis juste tricher et virer de bord la ligne par défaut à la fin de votre requête . Garantir que les types par défaut après un résultat véritable possible, et limite à votre première ligne:

SELECT TOP 1 * FROM (
    SELECT 1 AS TaskExists, CASE ... END AS PressReady, CASE ... AS WowYouHaveALongFieldNameHere 
    FROM Task 
    WHERE TaskID = 55555 

    UNION 

    -- default if no matching row 
    SELECT 0,    0,       0 
) ORDER BY TaskExists DESC; 

Vous pouvez trouver ce plus facile à lire que les alternatives impliquant des fonctions d'agrégation ou forcer une jointure et COALESCE/ISNULLing, etc.

Questions connexes