SQL Server 上的高效 ISNUMERIC() 替换?
因此,我花了 5 个小时排除了一个问题,结果发现该问题不仅是由于 旧的不可靠 ISNUMERIC
但看起来我的问题仅在 UDF 其中 ISNUMERIC 时出现
声明为 WITH SCHEMABINDING
并在存储过程中调用(我需要做很多工作才能将其提取到测试用例中,但我的第一个需要是替换它与可靠的东西)。
有关 ISNUMERIC()
的良好、高效替代方案的任何建议。 显然,int
、money
等确实需要有所变化,但是人们使用的是什么(最好是在 T-SQL 中,因为在这个项目中,我受到限制)到 SQL Server,因为这是一个大容量 SQL Server 到 SQL Server 数据处理任务)?
So I just spent 5 hours troubleshooting a problem which turned out to be due not only to the old unreliable ISNUMERIC
but it looks like my problem only appears when the UDF in which ISNUMERIC
is declared WITH SCHEMABINDING
and is called within a stored proc (I've got a lot of work to do to distill it down into a test case, but my first need is to replace it with something reliable).
Any recommendations on good, efficient replacements for ISNUMERIC()
. Obviously there really need to be variations for int
, money
, etc., but what are people using (preferably in T-SQL, because on this project, I'm restricted to SQL Server because this is a high-volume SQL Server to SQL Server data processing task)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果您运行的是 SQL Server 2012,则可以使用 T-SQL 函数 TRY_CAST() 或 TRY_CONVERT(),正如 Bacon Bits 在评论中提到的那样:
如果您使用的是 SQL 2008 R2 或更早版本,则必须使用 . NET CLR 函数,并包装 System.Decimal.TryParse()。
You can use the T-SQL functions TRY_CAST() or TRY_CONVERT() if you're running SQL Server 2012 as Bacon Bits mentions in the comments:
If you're using SQL 2008 R2 or older, you'll have to use a .NET CLR function, and wrap System.Decimal.TryParse().
根据验证的环境和性能特征,我有时会使用 LIKE 表达式的变体。 例如:
请注意,这个具体示例相当幼稚。 它不保证该值对于转换为特定数据类型是有效的。 如果您需要的话,它也不允许使用 +/- 符号或小数点。
Depending on the circumstances and the performance characteristics of the validation, I sometimes use a variation of the LIKE expression instead. For example:
Note that this specific example is fairly naive. It doesn't guarantee that the value is valid for conversion to a particular data type. It also doesn't allow for +/- signs or decimal points if you need those.
另一种选择可能是用 C 等语言编写扩展存储过程,将其放入 DLL 中并可供 SQL Server 使用。
我不认为这需要太多代码行,而且它可能比在 .NET 中编写托管存储过程更快,因为您不会因加载 CLR 而产生额外的监听。
这里有一个信息:
http://msdn.microsoft.com/en-us/library/ms175200。下面
是一些可能适合您的 C++ 代码:
Another option might be to write an extended stored procedure in a language such as C, make it into a DLL and make it available to SQL Server.
I don't imagine it would take too many lines of code to do, and it probably would be faster than writing a Managed Stored Procedure in .NET, because you wouldn't incur the extra overheard from loading the CLR.
Here's a tidbit of information:
http://msdn.microsoft.com/en-us/library/ms175200.aspx
Here's some C++ code that might work for you:
一般来说,作为一种实践,我尽量不要让非类型化数据进入数据库,因为它更适合在应用程序层处理它,或者批量导入在 SQL Integration Services 中处理它,以便数据从正确的类型中输入开始。
过去我不得不这样做很多次,通常最快的方法是编写自己的用户定义函数来验证数据是否采用您期望的格式,因为大多数时候调用扩展存储过程的开销或用于简单验证的托管代码比仅在 T-SQL 中执行要慢。
Generally as a practice, I try not to let untyped data into the database, as it is better more suited to either handle it at the application layer, or for batch imports handle it in SQL Integration Services so that the data comes in typed correctly from the start.
I have had to do it many times in the past and usually the fastest way is to write your own user defined function to verify the data is in the format you expect, as most of the time the overhead to calling out to an extended stored proc or managed code for simple validation is slower than just doing it in T-SQL.
遵循 .NET CLR 路线,您可以使用正则表达式,特别是如果您期望特定范围的数字。
SQL 2005 和正则表达式
Following the .NET CLR route, you could go with a regular expression, particularly if you expect a certain range of numbers.
SQL 2005 and Regular Expressions
根据 Microsoft 支持,替换 UDF 函数的唯一有效方法是编写自己的 .NET 函数版本。
当然,如果您的数据库管理员允许的话:)。
我的没有:(。
According to Microsoft support the only efficient way to replace UDF function is to write your own .NET function version.
Of course, if your database admin allows that :).
Mine doesn't :(.
您是否曾经要处理您自己(人类)语言之外的数字系统,例如中文等? 如果是这样,我建议使用 libuninum 库。
Are you ever going to be handling number systems outside of your own (human) language, like Chinese etc? If so, I'd suggest using the libuninum library.
如何实现这两个功能:
原始来源
How about implementing these two functions:
Original Source
对于 SQL Server 2005 及更高版本...利用 try/catch...
打印 0。
更改 @test = '01234' 或 @test = '01234.5' 并打印 1。
For SQL Server 2005 and above.... take advantage of try/catch...
prints 0.
Change @test = '01234' or @test = '01234.5' and it prints 1.
IsNumeric() 似乎对空格、“D”、“E”、美元符号和各种其他字符有问题。 我们通常想要的是告诉我们 CAST 或 CONVERT 是否会成功。 这个 UDF 虽然不是最快的解决方案,但对我来说效果很好。
IsNumeric() seems to have problems with spaces, 'D', 'E', dollar signs and all sorts of other characters. What we typically want is something that tells us whether a CAST or CONVERT will succeed. This UDF, while not the fastest solution, has worked very well for me.
从 SQL 2012 开始,您可以使用 TRY_PARSE() 函数代替 ISNUMERIC()。
SQL 2012 onwards, you can use TRY_PARSE() function instead of ISNUMERIC().