Usando uma função em uma consulta que retorna um string ou um nulo
-
03-07-2019 - |
Pergunta
Eu quero juntar 2 mesas 'addresses'
e 'user_info'
em user_id
e app_id
(Que é um número, ou é nulo), como estes exemplos 2:
select * from user_info
left outer join addresses on addresses.user_id = user_info.user_id
and addresses.app_id is null
select * from user_info
left outer join addresses on addresses.user_id = user_info.user_id
and addresses.app_id = 1234
O que o app_id deve ser é complicado e eu escrevi uma função para devolvê-lo. Ele retorna uma string, o que seria, por exemplo, "é nulo" ou "= 1234". Estou tentando chamá-lo com esta sintaxe:
select * from user_info
left outer join addresses on addresses.user_id = user_info.user_id
and addresses.app_id dbo.fnGetAppId(addresses.user_id)
Eu recebo este erro:
Msg 4145, Nível 15, estado 1, linha 3 An expressão de tipo não booleano especificado num contexto em que um condição é esperado, perto 'dbo'.
Eu gostaria de manter a consulta muito simples, pois é sem ter que determinar se a função está retornando um nulo ou não.
Você pode sugerir a melhor maneira de manter a consulta chamada muito simples?
(Eu estou no sql server 2005).
Solução
NULL! = NULL. Se qualquer address.app_id = NULL ou fnGetAppID = NULL, a comparação falhará. Eu ia escrever a comparação como:
coalesce(address.app_id, 'NULLSTRING') = coalesce(dbo.fnGetAppID(addresses.user_id), 'NULLSTRING')
Outras dicas
Parece que você está faltando apenas um sinal =
addresses.app_id dbo.fnGetAppId (addresses.user_id)
em vez de
addresses.app_id = dbo.fnGetAppId (addresses.user_id)
Então, se fnGetAppId é nulo, então esta consulta é semelhante ao seguinte?
select * from user_info left outer join addresses on addresses.user_id = user_info.user_id and null
Eu duvido que é o que você quer. :)
Você pode querer fazer uma verificação simples na sua lógica, antes de chamar a consulta, para tratar adequadamente um nulo para fnGetAppId e como Clyde mencionado você também precisa de um sinal = para um não-nula
.
Como James Black apontou, você tem e onde você provavelmente vai querer WHERE. Além disso, eu sugiro que você faça a função de um booleano um (passando address.app_id a ele como mais um argumento), para que ele possa realizar uma é nulo ou = 1234 como apropriado (solução COALESCE de Bill é inteligente, na verdade, mas colocando a comparação adequada dentro da função é mais simples, IMO).