2009-04-16 43 views
6

Tôi đang đấu tranh với một thủ tục T-SQL và tôi hy vọng bạn có thể giúp đỡ.Thủ tục T-SQL đưa ra kết quả boolean

Tôi cần phải biết nếu

  1. Một hàng tồn tại trong một bảng cho một ID cho
  2. Nếu một (hoặc nhiều) không tồn tại thì một mới nhất đã ID khác thiết lập để 5.

Vì vậy, bảng đầu tiên chúng ta cần để có được hàng ra khỏi có hai ID có liên quan: CaseID và LocationID, đây là cả hai số nguyên. Bảng thứ hai có 1 ID có liên quan được gọi là StateID.

Hiện tại tôi có thể nhận được hàng tồn tại trong một phần bảng nhưng ngay sau khi tôi cố gắng làm bất cứ điều gì Trình quản lý doanh nghiệp đưa ra lỗi cú pháp trước câu lệnh END.

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 

Có thể có cách để nhận được những gì tôi cần trong JOIN hoặc điều gì đó nhưng tôi là người mới hoàn thành ở đây.

Cách dễ nhất (hiểu) để kiểm tra StateID không phải là 5 và trả về kết quả là đúng/sai? (Tôi biết SQLServer không có kiểu boolean nhưng thay vào đó có kiểu Bit.)

Cũng theo một kiểu dáng: Các giá trị trong ID có trường văn bản liên kết với chúng - CaseEvents.StateID có văn bản 'Đã đóng' chẳng hạn. Tôi có nên trả về các giá trị làm ID và sau đó thay thế ID trong mã hoặc trả về các đối tượng có ID đã được thay thế bằng văn bản không? Sẽ không bao giờ có hơn 20 hoặc 30 kết quả được trả về trong một bộ và bảng sẽ không bao giờ rất lớn vì phải mất 5 năm để có được 2000 kết quả trong đó.

LƯU Ý: Không thể sử dụng LINQ (hoặc bất kỳ thứ gì khác .NETty) vì điều này sẽ được gọi từ chương trình VB6.

Cập nhật:

Chỉ có 1 trường hợp có thể được mở tại một thời điểm vì vậy chỉ mục gần đây nhất sẽ là sự phù hợp.

Các tình huống có thể có là:

  1. Không có trường hợp từng mở. Điều này sẽ trả về 0.
  2. Trường hợp đã được mở trước đó, nhưng hiện đã đóng. Điều này cũng nên trả về 0.
  3. Trường hợp đã mở tồn tại. Điều này sẽ trả về 1.

Trả lời

8

Tôi nghĩ truy vấn này sẽ làm những gì bạn đang tìm kiếm; Lưu ý rằng truy vấn hiện tại của bạn có lỗi trong trường hợp có nhiều hơn một trường hợp, nó sẽ chỉ kiểm tra xem trường hợp nào đã xảy ra được chọn bởi truy vấn ban đầu được đóng (tất nhiên điều đó chỉ đúng nếu có thể có nhiều hơn một trường hợp) được gán cho một vị trí cụ thể).

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 
+0

Trong trường hợp của tôi, bạn chỉ có thể có 1 trường hợp mở tại thời điểm đó để kiểm tra xem mục cuối cùng có phải là đóng cửa sẽ đủ trong trường hợp này hay không. Tôi nên lưu ý điều này trong mô tả vấn đề. –

+0

Xin lỗi - tôi đoán tôi nên cụ thể hơn khi tôi nói "kiểm tra xem trường hợp cuối cùng có bị đóng hay không" - Đây không nhất thiết phải là lần gần nhất, thứ tự sẽ không cụ thể trừ khi bạn bao gồm một mệnh đề ORDER BY. –

+0

Bạn là người đã làm việc thẳng ra khỏi hộp, vì vậy bạn nhận được đánh dấu ngay cả khi nó không phải là dễ hiểu nhất. –

4

Kiểm tra xem điều này có phù hợp với bạn hay không. Đã chỉnh sửa

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 
+0

tôi nhận được Lỗi 156: Cú pháp không chính xác gần từ khóa 'BEGIN'.Không đúng Cú pháp gần từ khóa' THÌ '. –

+0

Kiểm tra lại, tôi đã sửa, thay đổi IF Cú pháp cho Cú pháp CASE –

+0

Tuy nhiên, hãy kiểm tra câu trả lời của Edoode, cũng rất tốt –

1

Điều này có thể làm việc tốt:

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 
+0

Đối với một số lý do này không thành công trên một trong hai trường hợp khi dữ liệu không tồn tại. Trường hợp 1 không có trường hợp nào được mở - điều này hoạt động. Trường hợp 2 là trường hợp đã được mở trước đó, nhưng bây giờ đã đóng - điều này không trả lại 1. Trường hợp 3 là nơi một trường hợp đã mở tồn tại - điều này sẽ trả về 1. –

+0

@graham. Với một số dữ liệu mẫu tôi có thể được hỗ trợ – edosoft

1

Hãy thử điều này:

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 
2

Rất nhiều cách để giải quyết việc này, đây là một:

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 [email protected]) 
BEGIN 
    SELECT 1 
END 
ELSE 
BEGIN 
    SELECT 0 
END 
GO 
-1
create procedure abc (id int) 
as 
declare @count int 
begin 
select @count=count(anycolumn) from table 
where [email protected] 
if @count>0 
return 1 
else 
return 0 
end 
+0

Điều này không làm những gì tôi cần. –

Các vấn đề liên quan