从我在.NET 3.5中的WinForms C#应用程序中,我在SQL Server中调用存储过程。
此存储过程必须始终返回结果集并将返回变量设置为0或1。
这是我的存储过程:
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
无论员工是否满足某些条件(第一个结果集),都会返回相同的数据。第一个结果集在满足条件时返回,第二个结果集在不满足第一个结果集的条件时返回,但不同之处在于,第一个结果集返回变量@HasRights
设置为1,第二个结果集设置为这允许我从c#代码中区分它们在图片框中显示图标或其他图标。
我的问题在于,我需要存储过程返回第一个结果集或第二个结果集,但不能同时返回两个结果集。例如,当不满足第一次选择的条件时,它返回空数据集,后跟第二次选择的结果集(非空)。在这种情况下,我只想要返回第二个选择的第二个结果集(不是第一个为空)。那怎么办呢?
我知道我首先可以使用EXISTS作为第一个选择,如下所示:
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
这种方法的问题在于第一次选择重复两次:首先检查是否存在,第二次是否存在以便返回结果集,我想避免这种情况。
有什么想法吗?
答案 0 :(得分:1)
最后,我将存储过程重写为以下内容:
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