UTNianos

Versión completa: [Ayuda] Cursores en T-SQL
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Buenas tardes,

Estoy practicando crear cursores en T-SQL y el sql server me devuelve el siguiente mensaje de error:
"La subconsulta ha devuelto más de un valor, lo que no es correcto cuando va a continuación de =, !=, <, <=, >, >= o cuando se utiliza como expresión."

Necesito saber qué es lo que estoy haciendo mal.

El Script que ejecuté es el siguiente:
USE [PARCIAL ]
GO

-- Declaración Variables a utilizar
DECLARE @Cant INT
SET @Cant = 0
DECLARE @Pregunta INT
SET @Pregunta = (SELECT TOP 1 pregunta FROM PARCIAL.Logs)
DECLARE @PregAnterior INT
SET @PregAnterior = @Pregunta
DECLARE @EsCorrecta CHAR (1)
SET @EsCorrecta = (SELECT esCorrecta FROM PARCIAL.Respuestas WHERE pregunta = @Pregunta)
DECLARE @CondAnterior CHAR (1)
SET @CondAnterior = @Cant
DECLARE Maximo INT
SET Maximo = 0

-- Declaración del cursor
DECLARE Cursor_Cantidades CURSOR GLOBAL
SCROLL

FOR SELECT P.idPregunta
FROM PARCIAL.Preguntas AS P INNER JOIN PARCIAL.Logs AS L
ON L.pregunta = P.idPregunta INNER JOIN PARCIAL.Respuestas AS R
ON R.idRespuesta= L.respuesta
ORDER BY L.fechaHora

-- Apertura del cursor
OPEN Cursor_Cantidades

-- Lectura de la primera fila del cursor
FETCH Cursor_Cantidades INTO @Cant
WHILE ((@@FETCH_STATUS = 0) AND (@CondAnterior=@EsCorrecta))
BEGIN
IF (@PregAnterior=@Pregunta)
SET @Cant = @Cant + 1
-- Lectura de la siguiente fila de un cursor
FETCH Cursor_Cantidades INTO @Cant
SET @Pregunta = (SELECT pregunta FROM PARCIAL.Logs)
-- Fin del bucle WHILE
END

IF (@Maximo <= @Cant)
SET Maximo = @Cant

-- Cierra el cursor
CLOSE Cursor_Cantidades
Hola!,
El error te lo devuelve el SQL ya que vos podes asignar un solo elemento a cada variable y no varios. En otras palabras, si tu asignación depende de un resultado de una query debes asegurarte que devuelve 1 solo registro.

Sin mas aclaración, el error puede estar acá:
SET @Pregunta = (SELECT pregunta FROM PARCIAL.Logs)

Si ese select devuelve muchos registros, no te va a permitir realizar la asignación.

Cualquier cosa avisame.
Lo que quise hacer ahí es asignarle el valor de pregunta del próximo registro que recorre el cursor. Cómo debería hacerlo?
(11-12-2016 22:09)Silvina Paula escribió: [ -> ]Lo que quise hacer ahí es asignarle el valor de pregunta del próximo registro que recorre el cursor. Cómo debería hacerlo?

Si queres que lo lea el cursor, bajo mi consideracion, tendrias que cambiar el query generador del cursor,

FOR SELECT P.idPregunta, P.pregunta
FROM PARCIAL.Preguntas AS P INNER JOIN PARCIAL.Logs AS L
ON L.pregunta = P.idPregunta INNER JOIN PARCIAL.Respuestas AS R
ON R.idRespuesta= L.respuesta
ORDER BY L.fechaHora

FETCH Cursor_Cantidades INTO @Cant, @Pregunta

(11-12-2016 22:09)Silvina Paula escribió: [ -> ]Lo que quise hacer ahí es asignarle el valor de pregunta del próximo registro que recorre el cursor. Cómo debería hacerlo?

Si queres pasanos el enunciado del ejercicio y entre todos te ayudamos a resolverlo.
Para hacer eso debes poner un WHERE en la asignación obteniendo la pregunta para un ID de Pregunta dado.
Para lo que tenes hecho sería:



SET @Pregunta = (SELECT pregunta FROM PARCIAL.Logs WHERE PREGUNTA = @Cant)


Ahí lo pude solucionar, ya funciona. Les dejo el script actualizado:

USE [PARCIAL ]
GO

-- Declaración Variables a utilizar
DECLARE @Cant INT
SET @Cant = 0
DECLARE @Pregunta INT
DECLARE @PregAnterior INT
SET @PregAnterior = (SELECT TOP 1 pregunta FROM PARCIAL.Logs)
DECLARE @EsCorrecta CHAR (1)
SET @EsCorrecta = (SELECT TOP 1 esCorrecta FROM PARCIAL.Respuestas R INNER JOIN PARCIAL.Logs L
ON L.respuesta=R.idRespuesta WHERE R.pregunta = 2)
DECLARE @CondAnterior CHAR (1)
SET @CondAnterior = @Cant
DECLARE Maximo INT
SET Maximo = 0

-- Declaración del cursor
DECLARE Cursor_Cantidades CURSOR GLOBAL
SCROLL

FOR SELECT L.pregunta
FROM PARCIAL.Logs AS L INNER JOIN PARCIAL.Respuestas AS R
ON R.idRespuesta= L.respuesta
WHERE R.esCorrecta = @EsCorrecta
ORDER BY L.fechaHora

-- Apertura del cursor
OPEN Cursor_Cantidades

-- Lectura de la primera fila del cursor
FETCH Cursor_Cantidades INTO @Pregunta
WHILE ((@@FETCH_STATUS = 0) AND (@CondAnterior=@EsCorrecta))
BEGIN
IF (@PregAnterior=@Pregunta)
SET @Cant = @Cant + 1
-- Lectura de la siguiente fila de un cursor
FETCH Cursor_Cantidades INTO @Pregunta

-- Fin del bucle WHILE
END

IF (@Maximo <= @Cant)
SET Maximo = @Cant

-- Cierra el cursor
CLOSE Cursor_Cantidades

PRINT Maximo

-- Liberar el cursor
Deallocate Cursor_Cantidades
hola! tenes el enunciado del parcial?
URLs de referencia