Эффективный ISNUMERIC () замены на SQL Server?

17
задан Tieson T. 29 November 2015 в 23:31
поделиться

10 ответов

Можно использовать функции T-SQL TRY_CAST () или TRY_CONVERT () при выполнении SQL Server 2012 как упоминания Битов С беконом в комментариях:

SELECT CASE WHEN TRY_CAST('foo' AS INT) IS NULL THEN 0 ELSE 1 END

SELECT CASE WHEN TRY_CAST(1 AS INT) IS NULL THEN 0 ELSE 1 END

при использовании SQL 2008 R2 или старше необходимо будет использовать функцию CLR.NET и перенести Систему. Десятичное число. TryParse ().

22
ответ дан 30 November 2019 в 10:39
поделиться

Другая опция могла бы состоять в том, чтобы записать расширенную хранимую процедуру на языке, таком как C, превратить его в DLL и сделать его доступным для SQL Server.

я не предполагаю, что потребовалось бы слишком много строк кода, чтобы сделать, и это, вероятно, будет быстрее, чем запись Управляемой Хранимой процедуры в.NET, потому что Вы не подверглись бы дополнительному, подслушавшему от загрузки CLR.

Вот лакомый кусочек информации: http://msdn.microsoft.com/en-us/library/ms175200.aspx

Вот является некоторым кодом C++, который мог бы работать на Вас:

using namespace std;

int checkNumber() {
  int number = 0;
  cin >> number;
  cin.ignore(numeric_limits<int>::max(), '\n');

  if (!cin || cin.gcount() != 1)
    cout << "Not a number.";
  else
    cout << "Your entered: " << number;
  return 0;
}
6
ответ дан 30 November 2019 в 10:39
поделиться

В зависимости от обстоятельств и рабочих характеристик проверки, я иногда использую изменение ПОДОБНОГО выражения вместо этого. Например:

NOT LIKE '%[^0-9]%'

Примечание, что этот определенный пример довольно наивен. Это не гарантирует, что значение допустимо для преобразования в конкретный тип данных. Это также не допускает +/-знаки или десятичные точки при необходимости в них.

16
ответ дан 30 November 2019 в 10:39
поделиться

Обычно как практика, я пытаюсь не позволить невведенным данным в базу данных, поскольку это лучше больше подходит или обрабатывать его на прикладном уровне, или для паектных импортов обрабатывают его в Услугах по интеграции SQL так, чтобы данные вошли введенные правильно от запуска.

я должен был делать это много раз в прошлом, и обычно самый быстрый путь состоит в том, чтобы записать Вашу собственную определяемую пользователем функцию, чтобы проверить, что данные находятся в формате, который Вы ожидаете, поскольку большую часть времени издержки к обращению к расширенному сохранили proc, или управляемый код для простой проверки медленнее, чем просто выполнение его в T-SQL.

2
ответ дан 30 November 2019 в 10:39
поделиться

После маршрута CLR.NET Вы могли пойти с регулярным выражением, особенно если Вы ожидаете определенный диапазон чисел.

SQL 2005 и Регулярные выражения

3
ответ дан 30 November 2019 в 10:39
поделиться

Согласно поддержке Microsoft только эффективные способ заменить функцию UDF состоит в том, чтобы записать Вашу собственную версию функции.NET.

, Конечно, если Ваш администратор базы данных позволяет это :).

Мой не делает :(.

1
ответ дан 30 November 2019 в 10:39
поделиться

Как насчет того, чтобы реализовать эти две функции:

CREATE FUNCTION dbo.isReallyNumeric  
(  
    @num VARCHAR(64)  
)  
RETURNS BIT  
BEGIN  
    IF LEFT(@num, 1) = '-'  
        SET @num = SUBSTRING(@num, 2, LEN(@num))  

    DECLARE @pos TINYINT  

    SET @pos = 1 + LEN(@num) - CHARINDEX('.', REVERSE(@num))  

    RETURN CASE  
    WHEN PATINDEX('%[^0-9.-]%', @num) = 0  
        AND @num NOT IN ('.', '-', '+', '^') 
        AND LEN(@num)>0  
        AND @num NOT LIKE '%-%' 
        AND  
        (  
            ((@pos = LEN(@num)+1)  
            OR @pos = CHARINDEX('.', @num))  
        )  
    THEN  
        1  
    ELSE  
    0  
    END  
END  
GO  

CREATE FUNCTION dbo.isReallyInteger  
(  
    @num VARCHAR(64)  
)  
RETURNS BIT  
BEGIN  
    IF LEFT(@num, 1) = '-'  
        SET @num = SUBSTRING(@num, 2, LEN(@num))  

    RETURN CASE  
    WHEN PATINDEX('%[^0-9-]%', @num) = 0  
        AND CHARINDEX('-', @num) <= 1  
        AND @num NOT IN ('.', '-', '+', '^') 
        AND LEN(@num)>0  
        AND @num NOT LIKE '%-%' 
    THEN  
        1  
    ELSE  
        0  
    END  
END  
GO

Первоисточник

0
ответ дан 30 November 2019 в 10:39
поделиться

Вы когда-либо будут системами счисления обработки за пределами Вашего собственного (человеческого) языка, как китайский язык и т.д.? Если так, я предложил бы использовать libuninum библиотека .

0
ответ дан 30 November 2019 в 10:39
поделиться

IsNumeric (), похоже, имеет проблемы с пробелами, 'D', 'E', знаками доллара и всевозможными другими символами. Обычно нам нужно что-то, что говорит нам, будет ли CAST или CONVERT успешным. Этот UDF, хотя и не самое быстрое решение, мне очень помог.

create function dbo.udf_IsNumeric(@str varchar(50))
  returns int
as
begin
  declare @rtn int
  select @rtn =
    case
      when ltrim(rtrim(@str)) in('.', '-', '-.', '+', '+.') then 0
      when ltrim(rtrim(@str)) like '%[^-+.0-9]%' then 0
      else isnumeric(@str)
    end
  return @rtn
end
0
ответ дан 30 November 2019 в 10:39
поделиться

Для SQL Server 2005 и более поздних версий .... воспользуйтесь функцией try / catch ...

declare @test varchar(10), @num decimal
select @test = '0123A'

begin try
    select @num = cast(@test as decimal)
    print '1'
end try 
begin catch
    print '0'
end catch

выводит 0.

Изменить @test = '01234' или @test = '01234.5', и он печатает 1.

1
ответ дан 30 November 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: