Criei com sucesso a função escalar FN_TotalBilled no SQL Server, que me dá o valor total faturado para uma empresa usando as tabelas Invoices(InvoiceID, InvoiceTotal,VendorID,..) e Vendors(VendorName, VendorID,.....), e eu posso fazer com que a função retorne um valor inteiro, MAS não consigo descobrir como fazer com que a função retorne um valor do tipo $Integer. Aqui está o que eu tenho:
CREATE FUNCTION Fn_TotalBilled (@VendorName VarChar (50) )
RETURNS Int
BEGIN RETURN (SELECT SUM(InvoiceTotal) FROM Invoices I join Vendors V
on I.VendorID=V.VendorID where VendorName = @VendorName ) ; END ;
Agora, posso obter um valor de retorno usando:
SELECT dbo.Fn_TotalBilled('CompanyName') ,
Que cospe um número inteiro.
MAS eu quero como retorno obter uma string $integer. Isto é o que estou tentando, que não está funcionando:
Select '$'+ dbo.Fn_TotalBilled('IBM')
Recebo a mensagem de erro: "Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '$' to data type int."
Eu então tentei:
Select CAST('$' AS Varchar) + dbo.Fn_TotalBilled('IBM')
Mas isso também não deu certo. Alguém pode me ajudar a obter uma string de retorno $dbo.Fn_TotallBilled? Também tentei alterar a função selecionando SELECT '$' + ...
O que mais eu posso fazer?
Parece que você espera que o inteiro seja convertido implicitamente em string. O que realmente acontece é o contrário - a string é convertida implicitamente em inteiro.
A versão mais simples do que você deseja é:
Mas:
Você não deve usar Varchar sem comprimento, é uma prática ruim. Nesse caso, talvez Varchar(16) serviria?
Você está perdendo centavos. A prática normal seria usar Decimal(16, 2) para armazená-lo ou talvez até menor. Também de acordo com a outra resposta, algumas pessoas preferem o tipo de dados Money por causa de casas decimais adicionais para fins de arredondamento que podem ser úteis se juros compostos estiverem envolvidos.
O T-SQL não fará a formatação regional adequada para você (embora 2012 tenha adicionado uma maneira na outra resposta).
Mas acima de tudo isso geralmente, e quase certamente, não é/não deveria ser feito em T-SQL. Você deve sempre passar valores numéricos brutos para o chamador e deixá-los fazer a conversão de moeda regional para você na camada de apresentação. É aí que ele pertence.
A única exceção que vi é quando incluí a figura em uma mensagem de erro interna, por exemplo, para me fornecer uma figura em que o saldo está errado para fins de depuração e isso não fluirá para o chamador.
Dadas tabelas:
E dados de amostra:
Dada a escolha, você geralmente deve preferir uma função com valor de tabela embutida em vez de uma função escalar ou de várias instruções por motivos de desempenho:
Um índice útil é:
Consulta usando um único VendorName:
Para vários nomes de fornecedores, use apply:
Se você precisar formatar o trabalho no SQL Server, use um dos métodos na resposta de srutzky ou
STR
:Observe que os tipos money e smallmoney não são particularmente populares. Você pode achar que o decimal funciona melhor.
Você não precisa converter o
'$'
para aVARCHAR
, pois já é umVARCHAR
tipo. Você precisa converter o valor que sai da função em uma string, pois atualmente é um arquivoINT
.No entanto, como se trata de moeda, você deve fazer as duas coisas a seguir:
Altere o tipo de retorno da função a ser
MONEY
(que é, neste caso, melhor queDECIMAL
, que ainda é melhor que oINT
tipo atual que está sendo usado).Use a função CONVERT , passando um valor de "estilo" do
1
qual formataMONEY
os valores digitados para strings, colocando uma vírgula após cada 3 dígitos à esquerda do ponto decimal. Isso, é claro, é válido para "en-US" e alguns outros locais, mas não para todos.Retorna:
Se você deseja uma localidade que não use esse formato, então você pode usar a função FORMAT (introduzida no SQL Server 2012) que funciona exatamente como o
String.Format
método .NET (provavelmente devido a ele realmente chamar o método .NET ;-) .FORMAT
função não é apenas reconhecer a localidade, mas também incluir o símbolo de moeda apropriado e no lado apropriado (veja o exemplo abaixo).FORMAT
é que ele não é exatamente super-rápido, então pode desacelerar as consultas que retornam muitas linhas. É algo que você precisará testar para ver como funciona para você.Exemplo:
Retorna: