2012-07-16 43 views
33

¿Hay alguna manera fácil de devolver un valor escalar único o predeterminado si la consulta no devuelve ninguna fila?Cómo devolver el valor predeterminado de la consulta SQL

En este momento tengo algo así como este ejemplo de código:

IF (EXISTS (SELECT * FROM Users WHERE Id = @UserId)) 
    SELECT Name FROM Users WHERE Id = @UserId 
ELSE 
    --default value 
    SELECT 'John Doe' 

Cómo hacer que en mejor forma sin usar IF-ELSE?

+0

crear un procedimiento almacenado para cualquier base de datos con la programación lógica adicional. –

Respuesta

59

Suponiendo que el nombre no es anulable y que Id es único por lo que puede coincidir con una fila como máximo.

SELECT 
    ISNULL(MAX(Name),'John Doe') 
FROM 
    Users 
WHERE 
    Id = @UserId 
+0

La versión más simple hasta el momento y +1 al mencionar el requisito único. –

+1

¿Funcionará esto cuando no se devuelvan las filas? –

+3

@ChrisGessler - Sí. Un 'MAX' sin un' GROUP BY' o 'HAVING' siempre devuelve una fila. –

21

Trate ISNULL o COALESCE:

SELECT ISNULL((SELECT TOP 1 Name FROM Users WHERE Id = @UserId), 'John Doe') 

El seleccione interior volverá nada si existe ningún usuario con este id, el isnull va a resolver este caso.

+0

+1 pero existe un pequeño riesgo de que la selección devuelva más de una fila en cuyo caso esto no funcionará. –

+6

No use 'COALESCE' ya que [esto evaluará la consulta secundaria dos veces] (http://connect.microsoft.com/SQLServer/feedback/details/336002/unnecessarily-bad-performance-for-coalesce-subquery) –

+0

Un pequeño trazador de líneas dulce, pero necesitarás agregar el top 1 (por si acaso) –

3

Puede soltar la instrucción if utilizando la siguiente construcción, pero eso no significa necesariamente que sea mejor.

SELECT Name FROM Users WHERE Id = @UserId UNION ALL 
SELECT 'John Doe' WHERE NOT EXISTS (SELECT Name FROM Users WHERE Id = @UserId) 
2

Trate isnull

SELECT IsNULL(Name, 'John Doe') FROM Users WHERE Id = @UserId 

Editar:

drop table users 
go 
create table users 
(id int,name varchar(20)) 
go 
insert into users select 1,'1' 
go 
declare @userid int 
set @userid = 1 
select isnull(username.username, 'John Doe') 
from (select @userid as userid) userid 
outer apply (SELECT name as username FROM Users WHERE Id = userid.userid) username 
--outer apply (SELECT name as username FROM Users WHERE Id = @userid) username 
+2

Esto requiere al menos 1 registro con un valor nulo para Name –

+0

My bad. Pensé que estaba obteniendo un valor nulo ... –

+0

Puede probar esto también –

2

supongo que se podría utilizar @@ ROWCOUNT para ver si se devolverá ninguna.

SELECT Name FROM Users WHERE Id = @UserId 
if(@@ROWCOUNT = 0) 
    SELECT 'John Doe' 

También podría utilizar una variable si está esperando una fila.

declare @name varchar(100) 
set @name = (select top 1 name from users where id = @userId) 
if(@name is null) set @name = 'John Doe' 
select @name 
2

Yo sugeriría que la mejor manera de hacerlo es primero declarar @name. Luego, establezca este valor en función de la identificación del usuario y luego, si @name es nulo, muestre el nombre predeterminado, de lo contrario, muestre el nombre ... Ese método sería más eficiente que cualquier otro método y será más legible. Para otros métodos, cualquier otro usuario debe pensar Mucho para saber qué está pasando a menos que haya un comentario agradable.

declare @userid int 
set @userid = 1 
select isnull(
       (select name from users where id = @userid), 
       'John Doe' 
       ) 
go 
--My preffered would be this one.. 
declare @name varchar(20),@userid int 
set @userid = 1 
select @name = name from users where id = @userid 
select isnull(@name,'John Doe') 
0
Try this 
`SELECT IFNULL(Name,'John Doe') FROM Users WHERE Id = @UserId)` 
Cuestiones relacionadas