Existe uma maneira no T-SQL de converter um nvarchar para int e retornar um valor padrão ou NULL se a conversão falhar?
116
Use a função TRY_CONVERT .
Crie uma função definida pelo usuário. Isso evitará os problemas mencionados por Fedor Hajdu em relação à moeda, números fracionários, etc:
CREATE FUNCTION dbo.TryConvertInt(@Value varchar(18))
RETURNS int
AS
BEGIN
SET @Value = REPLACE(@Value, ',', '')
IF ISNUMERIC(@Value + 'e0') = 0 RETURN NULL
IF ( CHARINDEX('.', @Value) > 0 AND CONVERT(bigint, PARSENAME(@Value, 1)) <> 0 ) RETURN NULL
DECLARE @I bigint =
CASE
WHEN CHARINDEX('.', @Value) > 0 THEN CONVERT(bigint, PARSENAME(@Value, 2))
ELSE CONVERT(bigint, @Value)
END
IF ABS(@I) > 2147483647 RETURN NULL
RETURN @I
END
GO
-- Testing
DECLARE @Test TABLE(Value nvarchar(50)) -- Result
INSERT INTO @Test SELECT '1234' -- 1234
INSERT INTO @Test SELECT '1,234' -- 1234
INSERT INTO @Test SELECT '1234.0' -- 1234
INSERT INTO @Test SELECT '-1234' -- -1234
INSERT INTO @Test SELECT '$1234' -- NULL
INSERT INTO @Test SELECT '1234e10' -- NULL
INSERT INTO @Test SELECT '1234 5678' -- NULL
INSERT INTO @Test SELECT '123-456' -- NULL
INSERT INTO @Test SELECT '1234.5' -- NULL
INSERT INTO @Test SELECT '123456789000000' -- NULL
INSERT INTO @Test SELECT 'N/A' -- NULL
SELECT Value, dbo.TryConvertInt(Value) FROM @Test
Referência: usei esta página extensivamente ao criar minha solução.
Sim :). Experimente isto:
ISNUMERIC()
tem alguns problemas apontados por Fedor Hajdu .Ele retorna verdadeiro para strings como
$
(é a moeda),,
ou.
(ambos são separadores)+
e-
.fonte
ISNUMERIC
para que esta resposta seja útil em dados nãoISNUMERIC
validados (e você não precisaria da verificação em primeiro lugar para dados devidamente validados). O autor reconhece a existência desses problemas, mas não os aborda.TRY_CONVERT
/TRY_CAST
, que se destina explicitamente a resolver a questão do OP. Esta resposta foi escrita antes do lançamento do SQL 2012.Prefiro criar uma função como TryParse ou usar o
TRY-CATCH
bloco T-SQL para obter o que deseja.ISNUMERIC nem sempre funciona conforme o esperado. O código fornecido antes falhará se você:
SET @text = '$'
O sinal $ pode ser convertido em tipo de dados de dinheiro, portanto,
ISNUMERIC()
retorna true nesse caso. Ele fará o mesmo para '-' (menos), ',' (vírgula) e '.' personagens.fonte
ISNUMERIC()
Retorna1
também para,
e.
.Como foi mencionado, você pode ter vários problemas se usar
ISNUMERIC
:Se você deseja uma conversão confiável, precisará codificar uma você mesmo.
Atualização : Minha nova recomendação seria usar uma conversão de teste intermediária
FLOAT
para validar o número. Esta abordagem é baseada no comentário de Adrianm . A lógica pode ser definida como uma função com valor de tabela embutida:Alguns testes:
Os resultados são semelhantes à resposta de Joseph Sturtevant , com as seguintes diferenças principais:
.
ou,
para imitar o comportamento deINT
conversões nativas .'1,234'
e'1234.0'
voltarNULL
.'00000000000000001234'
avalia para12
. Aumentar o comprimento do parâmetro resultaria em erros nos números que estouramBIGINT
, como os BBANs (números básicos de contas bancárias)'212110090000000235698741'
.Retirado : A abordagem abaixo não é mais recomendada, pois é deixada apenas para referência.
O snippet abaixo funciona com números inteiros não negativos. Ele verifica se sua string não contém nenhum caractere diferente de dígitos, não está vazia e não transborda (excedendo o valor máximo para o
int
tipo). No entanto, também forneceNULL
números inteiros válidos cujo comprimento excede 10 caracteres devido a zeros à esquerda.Se você quiser suportar qualquer número de zeros à esquerda, use o abaixo. As
CASE
instruções aninhadas , embora pesadas, são necessárias para promover a avaliação de curto-circuito e reduzir a probabilidade de erros (decorrentes, por exemplo, da passagem de um comprimento negativo paraLEFT
).Se você deseja oferecer suporte a inteiros positivos e negativos com qualquer número de zeros à esquerda:
fonte
Saudações.
Escrevi uma função escalar útil para simular a função TRY_CAST do SQL SERVER 2012 no SQL Server 2008.
Você pode ver isso no próximo link abaixo e nós nos ajudamos a melhorá-lo. Função TRY_CAST para SQL Server 2008 https://gist.github.com/jotapardo/800881eba8c5072eb8d99ce6eb74c8bb
Exemplo:
Por enquanto suporta apenas os tipos de dados INT, DATE, NUMERIC, BIT e FLOAT
Eu espero que você ache isso útil.
CÓDIGO:
fonte
A resposta de Joseph apontou ISNUMERIC também lida com notação científica como '1.3e + 3', mas sua resposta não lida com este formato de número.
Fundir para um dinheiro ou flutuação primeiro lida com as questões monetárias e científicas:
A função falhará se o número for maior que um bigint.
Se você quiser retornar um valor padrão diferente, deixe esta função para que seja genérica e substitua o nulo depois:
fonte
Eu sei que não é bonito, mas é simples. Experimente isto:
fonte
Minha solução para esse problema foi criar a função mostrada abaixo. Meus requisitos incluíam que o número deveria ser um inteiro padrão, não um BIGINT, e eu precisava permitir números negativos e positivos. Eu não encontrei uma circunstância em que isso falhe.
fonte