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 / 20177
Accepted
kmote
kmote
Asked: 2012-06-30 12:45:08 +0800 CST2012-06-30 12:45:08 +0800 CST 2012-06-30 12:45:08 +0800 CST

Usando FLOATs com RAISERROR

  • 772

Estou usando RAISERROR()para fornecer algumas funcionalidades básicas de teste de unidade (como aqui ), mas estou frustrado com a incapacidade de usar FLOATsna mensagem de erro. Sei que posso converter o float em uma string, mas estou usando RAISERRORem cada teste de unidade, não quero adicionar outra linha de código para cada teste. (Meus testes de unidade já são prolixos o suficiente!) Existe uma maneira de executar uma conversão/cast inlineRAISERROR dentro da lista de parâmetros? Ou há outra maneira de contornar essa deficiência?

Atualização: Então, em última análise, o que eu gostaria de fazer é o seguinte:

RAISERROR('Unit Test FAILED! %f', 11, 0, @floatParm)

Infelizmente, RAISERRORnão lida com %f ou floats em geral. Então eu tenho que fazer isso em vez disso:

DECLARE @str VARCHAR(40) = CAST(@floatParm AS VARCHAR(40))
RAISERROR('Unit Test FAILED! %s', 11, 0, @str)

... que parece uma bagunça quando está espalhado por dezenas de testes de unidade. Então, eu gostaria de resumir para algo assim:

RAISERROR('Unit Test FAILED! %s', 11, 0, CAST(@floatParm AS VARCHAR(40))

Mas isso me dá uma Incorrect syntax near 'CAST'mensagem. Não entendo por que isso é ilegal, mas é. Existe outro "one liner" que eu poderia usar aqui?

sql-server t-sql
  • 1 1 respostas
  • 7237 Views

1 respostas

  • Voted
  1. Best Answer
    Jon Seigel
    2012-07-02T07:57:10+08:002012-07-02T07:57:10+08:00

    Infelizmente, por qualquer motivo, você não pode fazer uma conversão em linha nesse contexto e RAISERRORnão suporta diretamente float, novamente, por qualquer motivo.

    Para completar esta resposta, aqui está o trecho relevante do MSDN , que tenho certeza que você já viu (nota: é o mesmo texto em todas as versões da documentação de 2005 a 2012):

    Cada parâmetro de substituição pode ser uma variável local ou qualquer um destes tipos de dados: tinyint , smallint , int , char , varchar , nchar , nvarchar , binary ou varbinary .


    A única solução razoável em que posso pensar seria escrever um procedimento armazenado para agrupar a RAISERRORchamada. Aqui está um ponto de partida:

    CREATE PROCEDURE [dbo].[MyRaiserror]
    (
        @message nvarchar(2048),
        @severity tinyint,
        @state tinyint,
        @arg0 sql_variant = NULL
    )
    AS
    BEGIN
    
        DECLARE @msg nvarchar(MAX) = REPLACE(@message, '%f', '%s');
        DECLARE @sql nvarchar(MAX) = N'RAISERROR(@msg, @severity, @state';
    
        DECLARE @int0 int, @char0 nvarchar(MAX), @bin0 varbinary(MAX);
    
        IF (@arg0 IS NOT NULL)
        BEGIN
            SET @sql += N', ';
    
            IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('tinyint', 'smallint', 'int'))
            BEGIN
                SET @int0 = CONVERT(int, @arg0);
                SET @sql += N'@int0';
            END
            ELSE IF (SQL_VARIANT_PROPERTY(@arg0, 'BaseType') IN ('binary', 'varbinary'))
            BEGIN
                SET @bin0 = CONVERT(varbinary(MAX), @arg0);
                SET @sql += N'@bin0';
            END
            ELSE
            BEGIN
                SET @char0 = CONVERT(nvarchar(MAX), @arg0);
                SET @sql += N'@char0';
            END
        END
    
        SET @sql += N');';
    
        EXEC sp_executesql
            @sql,
            N'@msg nvarchar(2048), @severity tinyint, @state tinyint, @int0 int, @bin0 varbinary(MAX), @char0 nvarchar(MAX)',
            @msg, @severity, @state, @int0, @bin0, @char0;
    
    END
    

    Infelizmente, não há uma maneira fácil de dimensionar isso para um número arbitrário de parâmetros... Provavelmente poderia ser feito usando SQL dinâmico aninhado complicado, o que seria divertido depurar. Vou deixar isso como um exercício para o leitor.

    Usei sql_varianta suposição de que, por motivos de uniformidade de código, o mesmo procedimento seria usado em todos os lugares, mesmo para tipos de valor suportados diretamente por RAISERROR. Além disso, isso pode ser criado como um procedimento armazenado temporário , se for apropriado.

    Veja como ficaria usando este procedimento:

    DECLARE @f float = 0.02345;
    DECLARE @i int = 234;
    DECLARE @s varchar(20) = 'asdfasdf';
    DECLARE @b binary(4) = 0xA0B1C2D3;
    DECLARE @d decimal(18, 9) = 152.2323;
    DECLARE @n int = NULL;
    
    EXEC [dbo].[MyRaiserror] N'Error message with no params.', 10, 1;
    EXEC [dbo].[MyRaiserror] N'Float value = %f', 10, 1, @f;
    EXEC [dbo].[MyRaiserror] N'Int value = %i', 10, 1, @i;
    EXEC [dbo].[MyRaiserror] N'Character value = %s', 10, 1, @s;
    EXEC [dbo].[MyRaiserror] N'Binary value = %#x', 10, 1, @b;
    EXEC [dbo].[MyRaiserror] N'Decimal value = %f', 10, 1, @d;
    EXEC [dbo].[MyRaiserror] N'Null value = %i', 10, 1, @n;
    

    Resultado:

    Error message with no params.
    Float value = 0.02345
    Int value = 234
    Character value = asdfasdf
    Binary value = 0xa0b1c2d3
    Decimal value = 152.232300000
    Null value = (null)
    

    Portanto, o resultado líquido é que você não obtém capacidade de formatação para floats (role o seu próprio), mas ganha a capacidade de produzi-los (decimal/numérico também!) Enquanto mantém a capacidade de formatação para os outros tipos.

    • 12

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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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