Можно использовать функции 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 ().
Другая опция могла бы состоять в том, чтобы записать расширенную хранимую процедуру на языке, таком как 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;
}
В зависимости от обстоятельств и рабочих характеристик проверки, я иногда использую изменение ПОДОБНОГО выражения вместо этого. Например:
NOT LIKE '%[^0-9]%'
Примечание, что этот определенный пример довольно наивен. Это не гарантирует, что значение допустимо для преобразования в конкретный тип данных. Это также не допускает +/-знаки или десятичные точки при необходимости в них.
Обычно как практика, я пытаюсь не позволить невведенным данным в базу данных, поскольку это лучше больше подходит или обрабатывать его на прикладном уровне, или для паектных импортов обрабатывают его в Услугах по интеграции SQL так, чтобы данные вошли введенные правильно от запуска.
я должен был делать это много раз в прошлом, и обычно самый быстрый путь состоит в том, чтобы записать Вашу собственную определяемую пользователем функцию, чтобы проверить, что данные находятся в формате, который Вы ожидаете, поскольку большую часть времени издержки к обращению к расширенному сохранили proc, или управляемый код для простой проверки медленнее, чем просто выполнение его в T-SQL.
После маршрута CLR.NET Вы могли пойти с регулярным выражением, особенно если Вы ожидаете определенный диапазон чисел.
Согласно поддержке Microsoft только эффективные способ заменить функцию UDF состоит в том, чтобы записать Вашу собственную версию функции.NET.
, Конечно, если Ваш администратор базы данных позволяет это :).
Мой не делает :(.
Как насчет того, чтобы реализовать эти две функции:
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
Вы когда-либо будут системами счисления обработки за пределами Вашего собственного (человеческого) языка, как китайский язык и т.д.? Если так, я предложил бы использовать libuninum библиотека .
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
Для 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.