Sql 从Varchar列中删除字母数字字符,然后转换为Float
我有一个实验室测试表,有120列,所有列的数据类型都是varchar,应该是FLOAT,但这些列也包含像^、*、a-Z、a-Z、逗号、带句号的句子这样的字符。最后。我使用以下函数保留所有数值,包括 问题是这个。点,如果我使用@KeepValues作为varchar50='%[^0-9]',那么它将删除所有点,例如1.05*L变为105,这不是我想要的 你能帮我解决这个问题吗?这会很有帮助,或者任何替代方案都会很好Sql 从Varchar列中删除字母数字字符,然后转换为Float,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我有一个实验室测试表,有120列,所有列的数据类型都是varchar,应该是FLOAT,但这些列也包含像^、*、a-Z、a-Z、逗号、带句号的句子这样的字符。最后。我使用以下函数保留所有数值,包括 问题是这个。点,如果我使用@KeepValues作为varchar50='%[^0-9]',那么它将删除所有点,例如1.05*L变为105,这不是我想要的 你能帮我解决这个问题吗?这会很有帮助,或者任何替代方案都会很好 Create Function [dbo].[RAC] (@Temp Va
Create Function [dbo].[RAC]
(@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare @KeepValues as varchar(50) = '%[^0-9.]%'
While PatIndex(@KeepValues, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
Return @Temp
End
我的T-SQL案例陈述是:
,CASE WHEN LTRIM(RTRIM(DBO.RAC([INR]))) NOT IN ('','.')
THEN round(AVG(NULLIF(CAST(DBO.RAC([INR]) as FLOAT), 0)), 2)
END AS [INR]
PATINDEX支持模式匹配,但只支持T-SQL模式,而让模式完成您需要的工作可能是不可能的。 听起来你需要使用一个正则表达式来实现这一点。你需要一个CLR用户定义函数,或者你可以通过编写一个应用程序,使用SQL Server外部来实现这一点 有标记的答案将帮助您获得所需的 以下是代码副本,以便于参考:
using System;
using System.Data;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString StripNonNumeric(SqlString input)
{
Regex regEx = new Regex(@"\D");
return regEx.Replace(input.Value, "");
}
};
因为您有SQL2012,所以可以利用该函数
您需要一个基本的正则表达式,它允许您获取两组数字之间有一个小数点的数字,或者可能是根本没有小数点的数字。这需要对正则表达式函数使用SQLCLR。你可以找到许多这样的例子,或者你可以使用免费提供的SQLCLR库,我是该库的作者,但是回答这个问题所需的函数在免费版本中
DECLARE @Expression NVARCHAR(100) = N'\d+(\.\d+)?(e[-+]?\d+)?';
SELECT
SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase') AS [TheNumber],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase')) AS [Float],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'Another test. New number 1.05e4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float2],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'One more test. Yup 1.05e-4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float3]
/*
Returns:
TheNumber Float Float2 Float3
1.05 1.05 10500 0.000105
*/
这种模式的唯一问题是,如果文本中有另一个数字,你确实说在你想要的句子之前有完整的句子。如果100%确定所需的值始终有一个小数,则可以使用更简单的表达式,如下所示:
\d+\.\d+(e[-+]?\d+)?
正则表达式允许可选的e/e+/e-表示法。您使用的是哪个版本的SQL Server?您好,麦克,我使用的是SQL Server 2012 R2try\u CONVERT。我以前从未见过像这样创建的int列表-好主意。谢谢!我已经用TRY_CONVERT再次更改了我的脚本,这比其他解决方案更相关。再次感谢…………谢谢你,非常欢迎!记住,如果正确答案解决了你的问题,就要标出正确答案。
DECLARE @Expression NVARCHAR(100) = N'\d+(\.\d+)?(e[-+]?\d+)?';
SELECT
SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase') AS [TheNumber],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase')) AS [Float],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'Another test. New number 1.05e4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float2],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'One more test. Yup 1.05e-4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float3]
/*
Returns:
TheNumber Float Float2 Float3
1.05 1.05 10500 0.000105
*/
\d+\.\d+(e[-+]?\d+)?