2011-01-20 11 views
15

Editar: El problema que tuve se derivó de una confusión de orden de parámetros en mi código. Agradezco sinceramente la ayuda de todos; mi comprensión SQL mejora cada vez que visita SO.Seleccione un valor escalar de una tabla

Estoy escribiendo un procedimiento almacenado que necesita seleccionar un poco de información de otra tabla para hacer su trabajo.

DECLARE @configVar int; 
SET @configVar = (SELECT ExampleSetting FROM Settings WHERE SettingID = 1); 
-- do something with @configVar to get the final result set 

Obviamente (para las personas con una mejor comprensión de SQL), lo anterior es incorrecto. Ningún error, excepto cuando se ejecuta el procedimiento almacenado, @configVar se establece en NULL. He comprobado dos veces la tabla de la que estoy SELECCIONANDO y me he asegurado de que existan los datos.

¿Alguien puede mostrarme dónde está mi malentendido y cómo debería corregirlo? Parece que esto podría ser un idioma común; ¿Cómo se logra esto normalmente?

Respuesta

30

TSQL le permite establecer las variables en la cláusula SELECT, usando:

SELECT @configVar = s.examplesetting 
    FROM SETTINGS s 
WHERE s.settingid = 1 

Esto supone que sólo hay un registro de la tabla donde el valor settingid es 1.

Véase la pregunta "TSQL - SET vs. SELECT when assigning variables?" para más información sobre el uso.

+0

@OMG Ponies es ese operador menos ¿no? –

+0

@Conrad Frix: corregido justo antes de ver tu comentario. Typo mientras agregué el alias de la tabla. –

+0

@OMG Ponies. simplemente me pregunto si fue algo que no había visto antes –

5
DECLARE @configVar int; 
SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1 
0

Usted debe hacer esto en su lugar:

SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1 

Tenga en cuenta que si la consulta devuelve más de una fila de la variable será igual al último valor devuelto en el conjunto.

+3

La declaración es incorrecta. No intentará establecerlo en "un conjunto". Funciona (nulo o valor) o hará una bomba (Subquery devolvió más de 1 valor) – RichardTheKiwi

+0

editado para eliminar la línea ofensiva – Matthew

10

Obviamente (para las personas con una mejor comprensión de SQL), lo anterior es incorrecto.

¿Por qué dices eso? Es perfectamente válida, incluso si que se puede escribir como

SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1; 

De hecho, se le dará un error en la primera forma cuando hay múltiples filas devueltas (prueba el siguiente consulta) que permite usted sabe que algo no es lo que espera, mientras que la 2da consulta sobre silenciosamente funciona usando el valor ExampleSetting del último registro coincidente.

DECLARE @configVar int; 
SET @configVar = (SELECT number FROM master..spt_values); 
-- Msg 512, Level 16, State 1, Line 2 
-- Subquery returned more than 1 value. 

Ejecutar este por sí mismo y es posible que vea algo que te sorprende

SELECT ExampleSetting FROM Settings WHERE SettingID = 1 

Si esto no devuelve ningún registro, por eso SET @configVar es NULL izquierda

FYI, esto es lo que he intentado y funcionó según lo anunciado

DECLARE @configVar int; 
SET @configVar = (SELECT top 1 number FROM master..spt_values); 
select @configVar; 
-- result: -32768 

Una excepción a por qué usaría el SELECT @var formulario en lugar de SET from subquery forma es que el primero deja la variable solo cuando la consulta no encuentra filas coincidentes, el segundo explícitamente establece en nulo.

DECLARE @configVar int; 
SET @configVar = 123; 
SET @configVar = (SELECT top 1 number FROM master..spt_values where 1=0); 
select @configVar; -- @configVar was set to NULL 

SET @configVar = 123; 
SELECT top 1 @configVar = number FROM master..spt_values where 1=0; 
select @configVar; -- @configVar is LEFT as 123 
+0

Usando el formato 'SET @configVar = (SELECT ...);', ¿tiene que usar los parens? Me pregunto si es por eso que obtuve el error de sintaxis que me trajo aquí. –

+1

Sí, tienes que hacerlo. De lo contrario, es un error de sintaxis. La sintaxis es lo que permite que el código sea preciso en lo que se pretende. – RichardTheKiwi

Cuestiones relacionadas