validar una parte numeros left isnan extraer convert cadena sql-server user-defined-functions isnumeric

sql-server - una - sql server where isnumeric



Eficientes reemplazos ISNUMERIC() en SQL Server? (11)

¿Alguna vez va a manejar sistemas numéricos fuera de su propio lenguaje (humano), como el chino, etc.? Si es así, sugeriría usar la biblioteca libuninum .

Así que acabo de pasar 5 horas solucionando un problema que se debió no solo al antiguo ISNUMERIC no ISNUMERIC sino que parece que mi problema solo aparece cuando el UDF en el que ISNUMERIC se declara WITH SCHEMABINDING y se llama dentro de un proceso almacenado (I '' Tengo mucho trabajo por hacer para convertirlo en un caso de prueba, pero mi primera necesidad es reemplazarlo por algo confiable.

Cualquier recomendación sobre reemplazos buenos y eficientes para ISNUMERIC() . Obviamente, tiene que haber variaciones para int , money , etc., pero ¿qué está usando la gente (preferiblemente en T-SQL, porque en este proyecto, estoy restringido a SQL Server porque este es un servidor SQL de alto volumen para SQL? Tarea de procesamiento de datos del servidor)?


Según el soporte de Microsoft, la única forma eficiente de reemplazar la función UDF es escribir su propia versión de la función .NET.

Por supuesto, si el administrador de su base de datos lo permite :)

El mío no :(.



Otra opción podría ser escribir un procedimiento almacenado extendido en un lenguaje como C, convertirlo en una DLL y ponerlo a disposición de SQL Server.

No me imagino que tomaría demasiadas líneas de código para hacer, y probablemente sería más rápido que escribir un Procedimiento almacenado administrado en .NET, porque no incurriría en el extra que se escuchó al cargar el CLR.

Aquí hay un tidbit de información: http://msdn.microsoft.com/en-us/library/ms175200.aspx

Aquí hay un código C ++ que podría funcionar para usted:

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; }


¿Qué hay de la implementación de estas dos funciones:

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

Fuente original


IsNumeric () parece tener problemas con los espacios, ''D'', ''E'', signos de dólar y todo tipo de otros personajes. Lo que normalmente queremos es algo que nos diga si un CAST o CONVERT tendrá éxito. Esta UDF, aunque no es la solución más rápida, me ha funcionado muy bien.

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


Para SQL Server 2005 y posteriores ... aproveche 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

impresiones 0.

Cambia @test = ''01234'' o @test = ''01234.5'' e imprime 1.


SQL 2012 en adelante, puede usar la función TRY_PARSE () en lugar de ISNUMERIC ().

SELECT TRY_PARSE(''123'' as int) as ''123'' ,TRY_PARSE(''abc'' as int) as ''abc''


Puede usar las funciones T-SQL TRY_CAST () o TRY_CONVERT () si está ejecutando SQL Server 2012 como Bacon Bits menciona en los comentarios:

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

Si usa SQL 2008 R2 o una versión anterior, deberá usar una función .NET CLR y ajustar System.Decimal.TryParse ().


Según las circunstancias y las características de rendimiento de la validación, a veces utilizo una variación de la expresión LIKE. Por ejemplo:

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

Tenga en cuenta que este ejemplo específico es bastante ingenuo. No garantiza que el valor sea válido para la conversión a un tipo de datos en particular. Tampoco permite signos +/- o decimales si los necesita.


En general, como práctica, trato de no dejar datos sin tipo en la base de datos, ya que es más adecuado manejarlos en la capa de la aplicación o importar lotes en SQL Integration Services para que los datos se tipean correctamente desde el comienzo.

He tenido que hacerlo muchas veces en el pasado y, por lo general, la forma más rápida es escribir tu propia función definida por el usuario para verificar que los datos estén en el formato que esperas, ya que la mayoría de las veces la sobrecarga a un proceso almacenado extendido o el código administrado para la validación simple es más lento que simplemente hacerlo en T-SQL.