我正在尝试使用SELECT语句检索的数据,该语句由各种人输入,以克为单位。因为似乎没有标准,所以这里是人们编写它的一些方式:
我目前在下面有此函数,该函数将所有数字字符返回到NVARCHAR中,然后我可以将其转换为十进制以用于计算。
ALTER FUNCTION [dbo].[fn_GetNumeric]
(@strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
在某些情况下,此方法确实可以正常工作,但是例如,任何写为“ 0.2 ...”的数据都将变成“ 2”,这在处理克和千克时无济于事。
我需要它输出到DECIMAL或NVARCHAR并保留小数位,以便0.2保持0.2不变,而0.200保持如此。
(字母只出现在数字的开头或结尾,永远不会以数字.
开头)
答案 0 :(得分:0)
您可以找到一些未使用的字符,并用它替换.0
。然后放回去:
BEGIN
DECLARE @intAlpha INT
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '.0', '#');
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '0.', '##');
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '.', '###');
SET @intAlpha = PATINDEX('%[^0-9#]%', @strAlphaNumeric)
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9#]%', @strAlphaNumeric )
END
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '###', '.')
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '##', '0.');
SET @strAlphaNumeric = REPLACE(@strAlphaNumeric, '#', '.0');
SELECT ISNULL(@strAlphaNumeric,0)
END
或仅添加.
:
PATINDEX('%[^0-9.]%', @strAlphaNumeric)
但是如果您使用类似te....st 5.0 kg
这样的字符串,则会遇到问题,因此最好将.0
替换为特殊内容。
请注意,在示例中,我用#
替换,但是您可以用其中五个替换,以使值更独特-例如,#####
。
答案 1 :(得分:0)
在T-SQL中进行字符串解析始终是一个挑战。但是在这种情况下,SUBSTRING可能会更容易。
您提到了这一点:字母永远只出现在数字的开头或结尾,
所以基本上,我们只需要找到数字在字符串中的开始和结束位置。
看看这个:
DECLARE @String NVARCHAR(100)
SET @String = 'This is k.g. or g it''s .0456 not g'
SELECT PATINDEX('%[0-9 ].%[0-9]%', @String ) --Where is the first occurance of a number
SELECT PATINDEX('%[0-9]%', REVERSE(@String)) --Flip the string and tell me from the other end where that number occurs
SELECT LEN(@String) - PATINDEX('%[0-9 ].%[0-9]%', REVERSE(@String)) - PATINDEX('%[0-9]%', @String ) +2 --substract those from the length and add 2, tells me how long it is.
--The above is basically where the number starts and it's length in the string.
--Then use substring to pull it all out.
SELECT SUBSTRING(@String, PATINDEX('%[0-9 ].%[0-9]%', @String ), LEN(@String) - PATINDEX('%[0-9]%', REVERSE(@String)) - PATINDEX('%[0-9 ].%[0-9]%', @String ) +2)
--larger sample set
IF OBJECT_ID('tempdb..#TestData') IS NOT NULL
DROP TABLE #TestData
CREATE TABLE #TestData (
NumberData NVARCHAR(100)
)
INSERT INTO #TestData (
[NumberData]
)
VALUES
('200g')
,('0.2KG')
,('0.200kg')
,('0.2')
,('0.2g(e)')
,('0.2000000k.g.')
,('grams 0.345')
,('This is k.g. 0.456 not g')
,('.456kg')
SELECT *, SUBSTRING([NumberData], PATINDEX('%[0-9 ].%[0-9]%', [NumberData] ), LEN([NumberData]) - PATINDEX('%[0-9]%', REVERSE([NumberData])) - PATINDEX('%[0-9 ].%[0-9]%', [NumberData] ) +2)FROM #TestData