AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 137884
Accepted
MSIS
MSIS
Asked: 2016-05-08 19:02:48 +0800 CST2016-05-08 19:02:48 +0800 CST 2016-05-08 19:02:48 +0800 CST

Sintaxe ao alterar string de retorno por concatenação?

  • 772

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?

sql-server sql-server-2012
  • 3 3 respostas
  • 261 Views

3 respostas

  • Voted
  1. Cody Konior
    2016-05-08T19:50:59+08:002016-05-08T19:50:59+08:00

    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 é:

    Select '$' + Cast(dbo.fn_TotalBill('IBM') As Varchar)
    

    Mas:

    1. Você não deve usar Varchar sem comprimento, é uma prática ruim. Nesse caso, talvez Varchar(16) serviria?

    2. 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.

    3. O T-SQL não fará a formatação regional adequada para você (embora 2012 tenha adicionado uma maneira na outra resposta).

    4. 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.

    • 3
  2. Best Answer
    Paul White
    2016-05-08T22:49:42+08:002016-05-08T22:49:42+08:00

    Dadas tabelas:

    CREATE TABLE dbo.Vendors
    (
        VendorID integer NOT NULL,
        VendorName nvarchar(50) NOT NULL,
    
        CONSTRAINT [PK dbo.Vendors VendorID]
        PRIMARY KEY CLUSTERED (VendorID),
    
        CONSTRAINT [UQ dbo.Vendors VendorName]
        UNIQUE NONCLUSTERED (VendorName)
    );
    
    CREATE TABLE dbo.Invoices
    (
        InvoiceID integer NOT NULL,
        InvoiceTotal money NOT NULL,
        VendorID integer NOT NULL,
    
        CONSTRAINT [PK dbo.Invoices InvoiceID]
            PRIMARY KEY CLUSTERED (InvoiceID),
    
        CONSTRAINT [FK dbo.Invoices VendorID]
            FOREIGN KEY (VendorID)
            REFERENCES dbo.Vendors (VendorID)
    );
    

    E dados de amostra:

    INSERT dbo.Vendors
        (VendorID, VendorName)
    VALUES
        (1, N'Vendor #1'),
        (2, N'Vendor #2');
    GO
    INSERT dbo.Invoices
        (InvoiceID, InvoiceTotal, VendorID)
    VALUES
        (1, $100.00, 1),
        (2, $200.50, 1),
        (3, $300.75, 1),
        (4, $123.45, 2);
    

    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:

    CREATE FUNCTION dbo.TotalBilledToVendor
    (
        @VendorName nvarchar(50)
    )
    RETURNS table
    WITH SCHEMABINDING
    AS
    RETURN
        SELECT
            Total = SUM(I.InvoiceTotal)
        FROM dbo.Invoices AS I
        JOIN dbo.Vendors AS V
            ON V.VendorID = I.VendorID
        WHERE
            V.VendorName = @VendorName;
    

    Um índice útil é:

    CREATE NONCLUSTERED INDEX
        [dbo.Invoices VendorID (InvoiceTotal)]
    ON dbo.Invoices (VendorID)
    INCLUDE (InvoiceTotal);
    

    Consulta usando um único VendorName:

    SELECT
        TBTV.Total
    FROM dbo.TotalBilledToVendor(N'Vendor #1') AS TBTV;
    

    Para vários nomes de fornecedores, use apply:

    SELECT
        V.VendorName, 
        TBTV.Total
    FROM dbo.Vendors AS V
    CROSS APPLY dbo.TotalBilledToVendor(V.VendorName) AS TBTV;
    

    Se você precisar formatar o trabalho no SQL Server, use um dos métodos na resposta de srutzky ou STR:

    SELECT
        N'£' + STR(TBTV.Total, 13, 2)
    FROM dbo.TotalBilledToVendor(N'Vendor #1') AS TBTV;
    

    Observe que os tipos money e smallmoney não são particularmente populares. Você pode achar que o decimal funciona melhor.

    • 3
  3. Solomon Rutzky
    2016-05-08T19:59:59+08:002016-05-08T19:59:59+08:00

    Você não precisa converter o '$'para a VARCHAR, pois já é um VARCHARtipo. Você precisa converter o valor que sai da função em uma string, pois atualmente é um arquivo INT.

    No entanto, como se trata de moeda, você deve fazer as duas coisas a seguir:

    1. Altere o tipo de retorno da função a ser MONEY(que é, neste caso, melhor que DECIMAL, que ainda é melhor que o INTtipo atual que está sendo usado).

    2. Use a função CONVERT , passando um valor de "estilo" do 1qual formata MONEYos 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.

      SELECT '$' + CONVERT(VARCHAR(30), dbo.Fn_TotalBilled(11134.6), 1);
      

      Retorna:

      $11,134.60
      

      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.Formatmétodo .NET (provavelmente devido a ele realmente chamar o método .NET ;-) .

      • O benefício da FORMATfunçã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).
      • A desvantagem 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:

      SELECT FORMAT(11134.6, N'C', N'fr-fr');
      

      Retorna:

      11 134,60 €
      
    • 2

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve