2009-04-16 9 views
6

Estoy luchando con un procedimiento de T-SQL y espero que pueda ayudar.Procedimiento de T-SQL dando un resultado booleano

Necesito saber si

  1. Existe una fila de una tabla para un determinado ID
  2. Si uno (o más) no existe, entonces el más reciente ha puesto a otro ID 5.

Así que la primera tabla que necesitamos para sacar la fila tiene dos ID relevantes: CaseID y LocationID, ambos son enteros. La segunda tabla tiene 1 identificación relevante llamada StateID.

Actualmente puedo ver si la fila existe en una parte de la tabla, pero tan pronto como trato de hacer algo Enterprise Manager da un error de sintaxis antes de la instrucción 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 

Probablemente es una manera de conseguir lo que necesito en un JOIN o algo, pero yo soy un novato aquí.

¿Cuál sería la manera más fácil (de entender) de verificar el StateID no es 5 y devolver el resultado como verdadero/falso? (Sé que SQLServer no tiene un tipo booleano, pero sí tiene un tipo Bit.)

También en cuestión de estilo: los valores en los ID tienen un campo de texto asociado a ellos - CaseEvents.StateID has el texto 'Cerrado', por ejemplo. ¿Debo devolver los valores como los ID y luego reemplazar el ID en el código o devolver los objetos con los ID ya reemplazados con el texto? Nunca se devolverán más de 20 o 30 resultados en un conjunto y la tabla nunca será muy grande, ya que se necesitan 5 años para obtener 2000 resultados en ella.

NOTA: No se puede usar linq (o cualquier otra cosa .NETty) porque esto se llamará desde un programa VB6.

actualización:

Sólo 1 caso puede ser abierto a la vez por lo que sólo el artículo más reciente sería de relevancia.

Las posibles situaciones a tener es:

  1. Ningún caso nunca se abrió. Esto debería devolver 0.
  2. Se ha abierto anteriormente una caja, pero ahora está cerrada. Esto también debería devolver 0.
  3. Existe un caso abierto. Esto debería devolver 1.

Respuesta

8

Creo que esta consulta hará lo que está buscando; Tenga en cuenta que su consulta actual tiene un error porque si hay más de un caso, solo comprobará si se cerró el caso que fue seleccionado por la consulta inicial (por supuesto, solo es cierto si es posible tener más de un caso) asignado a una ubicación particular).

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

En mi caso, solo puedes tener 1 maleta abierta en el momento, por lo que comprobar si el último elemento es un cierre será suficiente en esta instancia. Debo señalar esto en la descripción del problema. –

+0

Lo siento, creo que debería haber sido más específico cuando dije "verifique si el último caso está cerrado": no es necesariamente el más reciente, el pedido no será específico a menos que incluya explícitamente una cláusula ORDER BY. –

+0

La tuya fue la que salió directamente de la caja, por lo que obtienes el tic incluso si no es lo más fácil de entender. –

4

Compruebe si esto funciona para usted. Editado

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

I obtener un Error 156: Sintaxis incorrecta cerca de la palabra clave 'BEGIN'. Sintaxis incorrecta cerca de la palabra clave 'ENTONCES'. –

+0

Comprobar de nuevo, he corregido, cambiar si Sintaxis para CASO Sintaxis –

+0

Sin embargo, comprobar la respuesta de Edoode, que también es muy bueno –

1

Esto podría funcionar así:

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

Por alguna razón, esto falla en uno de los dos casos cuando existen datos. Caso 1: ningún caso se ha abierto, esto funciona. Caso 2: el caso se ha abierto previamente, pero ahora está cerrado; no se puede devolver. El caso 3 es donde existe un caso abierto: esto pasa devolviendo 1. –

+0

@graham. Con algunos datos de muestra podría ser de ayuda – edosoft

1

Prueba esto:

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

muchas maneras de solucionar esto, aquí está uno:

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

Esto no hace lo que necesitaba. –

Cuestiones relacionadas