我有幾列有分數字符串(即6 11/32)或小數(1.5)的值。是否有CAST
或CONVERT
調用可以將這些調用轉換爲一致的小數?將分數字符串轉換爲十進制
錯誤:
消息8114,級別16,狀態5,第1行 錯誤數據類型爲varchar轉換爲數字。
我可以避免做任何形式的解析嗎?
謝謝!
P.S.我在SQL Server Management Studio 2012
工作。
我有幾列有分數字符串(即6 11/32)或小數(1.5)的值。是否有CAST
或CONVERT
調用可以將這些調用轉換爲一致的小數?將分數字符串轉換爲十進制
錯誤:
消息8114,級別16,狀態5,第1行 錯誤數據類型爲varchar轉換爲數字。
我可以避免做任何形式的解析嗎?
謝謝!
P.S.我在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」)
我不知道任何數據庫系統或此問題的代碼框架,原生支持像6 11/32
這樣的字符串。您最好的選擇是在相關表格中添加一列,並用腳本對其中的實際值進行非規範化處理,或者在其上創建一個自動完成的視圖。但是,它會花費一些複雜的代碼,並且在SQL中完成它可能不是一個好主意。
Excel支持分數:) – 2014-11-20 23:35:09
雖然我曾經看到一些非常糟糕的Web應用程序使用Excel作爲他們的數據層,我不會將其完全稱爲「數據庫系統」;)Excel是最終用戶工具,因此支持最終用戶符號更有意義。 – 2014-11-20 23:38:05
分數類通常作爲開始OOP編程類的練習。這很容易做到,並且可以通過搜索「C#分數類」或「Java分數類」輕鬆找到。 – 2014-11-20 23:38:12
你需要解析。正如尼爾斯所說,這不是一個好主意;但它可以通過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
注意,這將失敗,如果通過實際上並不匹配形式的內容「毫米/ NN」,「XX毫米/ 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
不可讀的榮譽:)爲什麼backquotes雖然? – 2014-11-23 03:42:20
而我其實在想有人會發現它優雅:))哦,殘酷的世界! :))笑話分開,當然要感謝!至於反引號:習慣了MySQL(精確到PhpMyAdmin),需要那些正確處理數據庫/表/列名(不知道它們是否可以正常工作 - 可能它會 - 但我以某種方式得到了這種習慣) 。意識到這個問題是關於MS SQL的,但是老習慣很難(另外還應該工作)。這裏的一些故事爲雅:) – 2014-11-23 03:52:09
其實反引號* *不*工作在MS SQL,只是試過。可以是「雙引號」或[括號]。而MS SQL沒有'IF()'結構;它是'CASE當cond THEN val1 ELSE val2 END'時。對不起:( – 2014-11-23 16:04:24
比我的更健壯一點。 +1 – 2014-11-21 00:10:05