2017-07-16 1 views
0

Depuis mon application WinForms C# dans NET 3.5, j'appelle une procédure stockée dans SQL Server.SQL Server return only 1 resultset

Cette procédure stockée doit toujours revenir un jeu de résultats et une variable de retour réglé sur 0 ou 1.

Voici ma procédure stockée:

CREATE PROCEDURE [dbo].[HasRights] 
    @Id char(10), 
    @dept char(4) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @nRows int 
    DECLARE @HasRights BIT 

    SET @HasRights = 0 

    SELECT e.Id, d.DeptId, p.Name 
    FROM Employees e 
    INNER JOIN depts d on e.Id = d.Id 
    INNER JOIN EmpData p on e.Id = p.Id 
    LEFT JOIN OldEmployees o ON e.Id = o.Id 
    WHERE e.Id = @Id 
     AND o.Id IS NULL 
     AND d.DeptId = @dept 
     AND e.Type in (100, 200, 300) 

    SET @nRows = @@ROWCOUNT  --SCOPE_IDENTITY() would also work 

    IF @nRows > 0 
    BEGIN 
     SET @HasRights = 1 
    END 
    ELSE 
    BEGIN 
     SELECT e.Id, d.DeptId, p.Name 
     FROM Employees e  
     INNER JOIN depts d on e.Id = d.Id 
     INNER JOIN EmpData p on e.Id = p.Id 
     WHERE e.Id = @Id 
      AND d.DeptId = @dept 
    END 

    RETURN @HasRights 
END 

Indépendamment si l'employé satisfait certaines conditions (premier jeu de résultats) ou non, les mêmes données sont renvoyées. Premier jeu de résultats lorsque les conditions sont satisfaites et deuxième ensemble de résultats lorsque les conditions du premier jeu de résultats ne sont pas satisfaites, mais avec la différence que la première variable de retour de jeu de résultats @HasRights est définie sur 1 et que le deuxième jeu de résultats est défini sur 0 permettez-moi de C# code pour les distinguer et afficher une icône ou une autre dans une imagebox.

Mon problème ici, c'est que j'ai besoin de la procédure de stockage pour retourner le premier jeu de résultats ou le second, mais pas les deux en même temps. Par exemple, lorsque les conditions de premier choix ne sont pas satisfaites, il retourne un jeu de données vide suivi du jeu de résultats de la seconde sélection (non vide). Dans ce cas, je veux que seul le second jeu de résultats soit retourné (pas le premier vide). Alors, comment le faire?

Je sais que je peux d'abord utiliser un EXISTE pour la première sélectionnez comme ci-dessous:

CREATE PROCEDURE [dbo].[HasRights] 
    @Id char(10), 
    @dept char(4) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @nRows int 
    DECLARE @HasRights BIT 

    SET @HasRights = 0 

    IF EXISTS(SELECT e.Id, d.DeptId, p.Name 
       FROM Employees e 
       INNER JOIN depts d on e.Id = d.Id 
       INNER JOIN EmpData p on e.Id = p.Id 
       LEFT JOIN OldEmployees o ON e.Id = o.Id 
       WHERE e.Id = @Id 
       AND o.Id IS NULL 
       AND d.DeptId = @dept 
       AND e.Type in (100, 200, 300)) 
    BEGIN 
     SELECT e.Id, d.DeptId, p.Name 
     FROM Employees e 
     INNER JOIN depts d on e.Id = d.Id 
     INNER JOIN EmpData p on e.Id = p.Id 
     LEFT JOIN OldEmployees o ON e.Id = o.Id 
     WHERE e.Id = @Id 
     AND o.Id IS NULL 
     AND d.DeptId = @dept 
     AND e.Type in (100, 200, 300)    

     SET @HasRights = 1 
    END 
    ELSE 
    BEGIN 
     SELECT e.Id, d.DeptId, p.Name 
     FROM Employees e  
     INNER JOIN depts d on e.Id = d.Id 
     INNER JOIN EmpData p on e.Id = p.Id 
     WHERE e.Id = @Id 
      AND d.DeptId = @dept 
    END 

    RETURN @HasRights 
END 

Le problème avec cette approche est que la première sélection est répétée deux fois: d'abord lors de la vérification si cela existe et seconde si cela existe afin de retourner le jeu de résultats et je veux éviter cela.

Des idées?

+1

Vous pouvez le sélectionner dans une variable de la première table et le retourner à partir de la variable de table. La chose est probablement déjà mise en cache, donc cela n'a pas vraiment d'importance si vous l'exécutez deux fois. –

+0

Il y a probablement un moyen de bidouiller votre clause 'WHERE' pour la faire fonctionner mais je ne comprends pas votre logique –

+0

Je pense que je pourrais utiliser une requête et déterminer dans C# si l'employé HasRights en regardant le jeu de résultats. BTW, vous ne retournez pas '@ HasRights', à quoi cela sert-il? – Crowcoder

Répondre

1

Enfin j'ai réécrit la procédure stockée dans le suivant:

CREATE PROCEDURE [dbo].[HasRights] 
    @Id char(10), 
    @dept char(4) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @HasRights BIT 

    SET @HasRights = 0 

    IF EXISTS(SELECT TOP 1 
       FROM Employees e 
        INNER JOIN depts d on e.Id = d.Id 
        INNER JOIN EmpData p on e.Id = p.Id 
        LEFT JOIN OldEmployees o ON e.Id = o.Id 
       WHERE e.Id = @Id 
         AND 
        o.Id IS NULL 
         AND 
        d.DeptId = @dept 
         AND 
        e.Type in (100, 200, 300)) 
      ) 
    BEGIN 
     SET @HasRights = 1 
    END 

    SELECT e.Id, d.DeptId, p.Name 
    FROM Employees e 
      INNER JOIN depts d on e.Id = d.Id 
      INNER JOIN EmpData p on e.Id = p.Id    
    WHERE e.Id = @Id 
      AND 
      d.DeptId = @dept  

    RETURN @HasRights  
END 
+0

Cela ne semble pas avoir la même fonctionnalité que votre requête publiée à l'origine. Si c'est le cas, alors c'est à cause d'une information connue de vous seulement. –