Sql server 2005 给出布尔结果的T-SQL过程
我正在努力处理一个T-SQL过程,希望您能提供帮助 我需要知道 表中存在给定ID的行 如果确实存在一个或多个ID,则最新的ID将另一个ID设置为5。 因此,我们需要从中获取行的第一个表有两个相关的ID:CaseID和LocationID,它们都是整数。第二个表有一个名为StateID的相关ID 目前,我可以获取该行是否存在于表部件中,但只要我尝试执行任何操作,Enterprise Manager就会在END语句之前给出语法错误Sql server 2005 给出布尔结果的T-SQL过程,sql-server-2005,tsql,Sql Server 2005,Tsql,我正在努力处理一个T-SQL过程,希望您能提供帮助 我需要知道 表中存在给定ID的行 如果确实存在一个或多个ID,则最新的ID将另一个ID设置为5。 因此,我们需要从中获取行的第一个表有两个相关的ID:CaseID和LocationID,它们都是整数。第二个表有一个名为StateID的相关ID 目前,我可以获取该行是否存在于表部件中,但只要我尝试执行任何操作,Enterprise Manager就会在END语句之前给出语法错误 CREATE PROCEDURE [dbo].[HasActiveC
CREATE PROCEDURE [dbo].[HasActiveCase]
(
@LocationID INTEGER
)
AS
DECLARE @CaseID AS INTEGER
SELECT @CaseID=CaseID FROM dbo.Cases WHERE @LocationID=LocationID
SELECT CASE WHEN
@CaseID IS NULL
THEN
0
ELSE
-- do something here to check CaseEvents.StateID is not 5 (closed)
END
GO
也许有一种方法可以让我在加入或其他活动中得到我所需要的,但我在这里是一个完全的新手
检查StateID不是5并返回结果为真/假的最容易理解的方法是什么?我知道SQLServer没有布尔类型,但有位类型
还有一个关于样式的问题:ID中的值有一个与之关联的文本字段——例如CaseEvents.StateID有一个“Closed”文本。我应该以ID的形式返回值,然后在代码中替换ID,还是返回ID已替换为文本的对象?一个集合中返回的结果永远不会超过20或30个,表格也永远不会很大,因为需要5年才能得到2000个结果
注意:不能使用linq或任何其他.NETty,因为它将从VB6程序调用
更新:
一次只能打开一个案例,因此只有最近的项目才具有相关性
可能出现的情况是:
从来没有打开过一个案子。这应该返回0。
以前已打开过一个案例,但现在已关闭。这也应该返回0。
存在一个已打开的案例。这应该返回1。
检查这是否适合你。编辑
CREATE PROCEDURE [dbo].[HasActiveCase]
(
@LocationID INTEGER
)
AS BEGIN
DECLARE @CaseID AS INTEGER
SELECT @CaseID = CaseID FROM dbo.Cases WHERE @LocationID=LocationID
SELECT CASE WHEN
@CaseID IS NULL
THEN 0
ELSE CASE WHEN (SELECT COUNT(*) FROM CaseEvents WHERE StateID <> 5) > 0 THEN 0 ELSE 1 END
END
END
GO
我认为这个查询会满足您的需求;请注意,您现有的查询存在一个缺陷,即如果存在多个案例,它将只检查初始查询选择的任何案例是否已关闭。当然,只有在可能将多个案例分配到特定位置时,这才是正确的
SELECT @CaseID = dbo.Cases.CaseID
FROM dbo.Cases
JOIN dbo.CaseEvents ON dbo.Cases.CaseEventID = dbo.CaseEvents.CaseEventID
WHERE @LocationID = dbo.Cases.LocationID
AND 5 != dbo.CaseEvents.StateID
SELECT CASE WHEN @CaseID IS NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS CaseExists
这也可能奏效:
CREATE PROCEDURE [dbo].[HasActiveCase]
(
@LocationID INTEGER
)
AS
IF EXISTS (SELECT CaseID FROM dbo.Cases WHERE @LocationID=LocationID)
BEGIN
IF EXISTS (SELECT * FROM CaseEvents WHERE StateID <> 5)
SELECT 1 ELSE SELECT 0
END
ELSE
SELECT 0
GO
试试这个:
Select Case When Exists
(Select * From CaseEvents
Where CaseId =
(Select CaseID From Cases
Where LocationId = @Location)
And StateId = 5) -- Or <> 5 I'm not sure which you want here
Then 1 Else 0 End
有很多方法可以解决这个问题,这里有一个:
CREATE PROCEDURE [dbo].[HasActiveCase]
(
@LocationID INTEGER
)
AS
DECLARE @CaseID AS INTEGER
SELECT @CaseID=CaseID FROM dbo.Cases WHERE @LocationID=LocationID
if (@CaseId IS NULL)
BEGIN
SELECT 0
END
ELSE if EXISTS ( SELECT * FROM CaseEvents WHERE StatusId=5 and CaseId=@CaseId)
BEGIN
SELECT 1
END
ELSE
BEGIN
SELECT 0
END
GO
在我的例子中,您一次只能打开一个案例,因此在本例中,检查最后一项是否为闭包就足够了。我应该在问题描述中注意到这一点。抱歉-我想我在说检查最后一个案例是否结案时应该更具体-这不一定是最近的案例,除非您明确包含order BY条款,否则订单不会是具体的。您的订单是开箱即用的,因此,即使不是最容易理解的,也会得到勾号。我得到一个错误156:关键字“BEGIN”附近的语法不正确。关键字“THEN”附近的语法不正确。好的。这就像我在编辑问题中列出的检查2中的Edood一样失败。我刚刚编辑了答案,这只是更改结果顺序的问题,因为IF EXISTS方法对性能更友好,因为它将在找到第一个为true的实例时停止扫描表。由于某种原因,当数据确实存在时,这两种情况中的一种都会失败。案例1从来没有打开过——这是有效的。案例2表示案例之前已打开,但现在已关闭-返回1失败。案例3是一个打开的案例存在的地方-这通过返回1。@graham。有了一些样本数据,我可能会有所帮助。这并不能满足我的需要。
create procedure abc (id int)
as
declare @count int
begin
select @count=count(anycolumn) from table
where id=@id
if @count>0
return 1
else
return 0
end