簡體   English   中英

將小數字符串轉換為十進制

[英]Convert fractional string to decimal

我有一些列,這些列的值要么是小數字符串(即6 11/32),要么是小數(1.5)。 是否有CASTCONVERT調用可以將其轉換為一致的小數?

錯誤:

消息8114,級別16,狀態5,第1行將數據類型varchar轉換為數值時出錯。

我可以避免進行任何形式的解析嗎?

謝謝!

PS我正在使用SQL Server Management Studio 2012

CREATE FUNCTION ufn_ConvertToNumber(@STR VARCHAR(50))
RETURNS decimal(18,10)
AS
BEGIN
        DECLARE @L VARCHAR(50) = ''
        DECLARE @A DECIMAL(18,10) = 0
        SET @STR = LTRIM(RTRIM(@STR)); -- Remove extra spaces
        IF ISNUMERIC(@STR) > 0 SET @A = CONVERT(DECIMAL(18,10), @STR) -- Check to see if already real number
        IF CHARINDEX(' ',@STR,0) > 0
        BEGIN
            SET @L = SUBSTRING(@STR,1,CHARINDEX(' ',@STR,0) - 1 )
            SET @STR = SUBSTRING(@STR,CHARINDEX(' ',@STR,0) + 1 ,50 )
            SET @A = CONVERT(DECIMAL(18,10), @L)
        END
        IF CHARINDEX('/',@STR,0) > 0
        BEGIN
            SET @L = SUBSTRING(@STR,1,CHARINDEX('/',@STR,0) - 1 )
            SET @STR = SUBSTRING(@STR,CHARINDEX('/',@STR,0) + 1 ,50 )
            SET @A =  @A + ( CONVERT(DECIMAL(18,10), @L) / CONVERT(DECIMAL(18,10), @STR)  )
        END
        RETURN @A
END
GO

然后通過選擇dbo.ufn_ConvertToNumber('5 9/5')訪問它

您需要解析。 正如尼爾斯所說,這不是一個好主意。 但是可以使用T-SQL標量函數相當簡單地完成。

CREATE FUNCTION dbo.FracToDec ( @frac VARCHAR(100) )
RETURNS DECIMAL(14, 6)
AS
    BEGIN
        RETURN CASE 
            WHEN @frac LIKE '% %/%'
                THEN CAST(LEFT(@frac, CHARINDEX(' ', @frac, 1) -1) AS DECIMAL(14,6)) + 
                    ( CAST(SUBSTRING(@frac, CHARINDEX(' ', @frac, 1) + 1, CHARINDEX('/', @frac, 1)-CHARINDEX(' ',@frac,1)-1) AS DECIMAL(14,6)) 
                    / CAST(RIGHT(@frac, LEN(@frac) - CHARINDEX('/', @frac, 1)) AS DECIMAL(14,6)) )
            WHEN @frac LIKE '%/%'
                THEN CAST(LEFT(@frac, CHARINDEX('/', @frac, 1) - 1) AS DECIMAL(14,6)) / CAST(RIGHT(@frac, LEN(@frac) - CHARINDEX('/', @frac, 1)) AS DECIMAL(14,6))
            ELSE 
                CAST(@frac AS DECIMAL(14,6)) 
            END
    END
GO

-- Test cases
SELECT  dbo.FracToDec('22/7'), dbo.fracToDec('3.117'), dbo.fracToDec('7 3/4')

-- Output
-- 3.142857   3.117000   7.750000

請注意,如果傳遞的內容與形式“ mm / nn”,“ xx mm / nn”或實際十進制數不匹配,則此操作將失敗。

這是沒有功能和存儲過程的解決方案-僅出於樂趣。 首先,您必須創建一個新列(我稱其為decimal ),然后使用以下查詢從原始混合格式列(稱為inconsistent )轉換后的值填充該列:

UPDATE  "my_table"
SET     "decimals" = CASE WHEN CHARINDEX('/', "inconsistent") > 0
                          THEN CAST(CASE WHEN CHARINDEX(' ',
                                                        RTRIM(LTRIM("inconsistent"))) > 0
                                         THEN LEFT(RTRIM(LTRIM("inconsistent")),
                                                   CHARINDEX(' ',
                                                             RTRIM(LTRIM("inconsistent")))
                                                   - 1)
                                         ELSE '0'
                                    END AS FLOAT)
                               + CAST(SUBSTRING(RTRIM(LTRIM("inconsistent")),
                                                CHARINDEX(' ',
                                                          RTRIM(LTRIM("inconsistent")))
                                                + 1,
                                                CHARINDEX('/',
                                                          RTRIM(LTRIM("inconsistent")))
                                                - 1 - CHARINDEX(' ',
                                                              RTRIM(LTRIM("inconsistent")))) AS FLOAT)
                               / CAST(RIGHT(RTRIM(LTRIM("inconsistent")),
                                            LEN(RTRIM(LTRIM("inconsistent")))
                                            - CHARINDEX('/',
                                                        RTRIM(LTRIM("inconsistent")))) AS FLOAT)
                          ELSE CAST(RTRIM(LTRIM("inconsistent")) AS FLOAT)
                     END

我不知道有任何數據庫系統或代碼框架可用於本地支持6 11/32類的字符串。 最好的選擇是在相關表中添加一列,並使用腳本在其中對實際值進行歸一化,或者在其上創建一個自動執行此操作的視圖。 不過,這將需要一些復雜的代碼,而在SQL中完全不是一個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM