[英]How to convert varchar to float for calculation in SQL Server 2008R
[英]How to convert varchar(4) to float in SQL Server 2008?
我正在嘗試將我的數據庫字段從VARCHAR(4)
為FLOAT
。 這些字段中的某些值可能不是數字,因為這些字段之前沒有任何驗證。 我的主要目標是以float格式轉換任何integer
或decimal
值並保存在新數據庫字段中。 對於這個過程,我使用舊表中的INSERT SELECT STATEMENT
到新表中。 到目前為止,我有這行代碼用於轉換:
CASE WHEN LEN(LTRIM(RTRIM(hs_td2))) <> 0 AND ISNUMERIC(hs_td2) = 1 THEN CAST(LTRIM(RTRIM(hs_td2)) AS float) ELSE NULL END AS hs_td2
第一步我修剪值,然后檢查它是否為數字,然后轉換為float,否則設置為NULL。 使用上面的代碼我在Microsoft Studio中收到此錯誤消息:
Msg 8114, Level 16, State 5, Line 13
Error converting data type varchar to float.
第13行是我的SELECT
語句的開頭。 然后我也嘗試了這種轉換:
CASE WHEN LEN(LTRIM(RTRIM(hs_td2))) <> 0 AND ISNUMERIC(hs_td2) = 1 THEN CONVERT(FLOAT, LTRIM(RTRIM(hs_td2))) ELSE NULL END AS hs_td2
我得到了相同的錯誤消息。 我的字段中的值可能是這樣的:
10或5或-10或0.9或11.6或-11.89等......
我想知道isNumeric()
是否是我應該使用的最佳函數以及為什么我的代碼會產生上面列出的錯誤消息?
如果有人可以提供幫助,請告訴我。 謝謝!
不, ISNUMERIC
不是最好的功能。
從本質上講,這個問題之前已被問過,但不是這個問題:
Try_Convert for SQL Server 2008 R2
最受歡迎的答案建議轉換為XML以使用特定於XML的轉換函數:
DECLARE @T TABLE (v varchar(4));
INSERT INTO @T (v) VALUES
('1g23'),
('-1.8'),
('11.6'),
('akjh'),
('.'),
('-'),
('$'),
('12,5');
select
cast('' as xml).value('sql:column("V") cast as xs:float ?', 'float') as new_v
from @T
我將在下面留下我的第一個答案版本。
您很可能會收到轉換錯誤,因為服務器嘗試為表的每一行運行CAST(LTRIM(RTRIM(hs_td2)) AS float)
,而不僅僅是那些數字行。
當您嘗試使用WHERE ISNUMERIC(...) = 1
過濾器過濾掉非數字行時,通常會發生這種情況。 從技術上講,它也可能發生在CASE
表達式中。
這就是為什么他們在2012年增加了TRY_CONVERT
。
我嘗試編寫自己的用戶定義函數,該函數使用TRY-CATCH
並嘗試轉換給定值。 是的,它會很慢。
話雖如此,下面的例子與CASE
運行良好:
DECLARE @T TABLE (v varchar(4));
INSERT INTO @T (v) VALUES
('123'),
('-1.8'),
('11.6'),
('akjh'),
('123');
SELECT
CASE WHEN ISNUMERIC(v) = 1 THEN CAST(v AS float) ELSE NULL END AS new_v
FROM @T;
結果
+-------+
| new_v |
+-------+
| 123 |
| -1.8 |
| 11.6 |
| NULL |
| 123 |
+-------+
但是,如果我放一個.
或-
或$
value,如下:
INSERT INTO @T (v) VALUES
('123'),
('-1.8'),
('11.6'),
('akjh'),
('$');
查詢失敗:
將數據類型varchar轉換為float時出錯。
可能還有其他特殊字符及其組合, ISNUMERIC
不會抱怨。 這就是為什么我最初說整體而言, ISNUMERIC
並不是最好的功能。
如果是一次性轉換,您可以嘗試構建一個LIKE
表達式來捕獲數據中存在的所有特殊情況,但如果您需要可靠的通用解決方案,請升級到2012+並使用TRY_CONVERT
或編寫您的T- SQL UDF,或您的CLR UDF。
Sqlxml有足夠的力量來制造魔法。 當然,性能是問題所在。 但仍然比百萬條件更好
DECLARE @T TABLE (v varchar(4));
INSERT INTO @T (v) VALUES
('123'),('-1.8'),('11.6'),('akjh'),('$'),('-.'),('-.1'),(NULL);
declare @Xml xml = (SELECT v FROM @T T for xml auto,elements);
select T.v.value('v[1]','varchar(4)') v, T.v.value('max(v[1])','float') converted_v
from @xml.nodes('/T') T(v);
它取決於varchar列中的值
ISNUMBER()表示'。'等vaule 並且' - '將返回1,但是,當你CAST到FLOAT時它會失敗
對於諸如“3D2 ”之類的值的ISNUMBER(), “1e2 ”將返回1,並且可以是CAST到FLOAT,但是,您可能不希望將其視為數字。
您可以嘗試以下轉換
CASE WHEN
not LTRIM(RTRIM(hs_td2))like '%[^0-9.,-]%' -- Value only contains 0-9 . -
and LTRIM(RTRIM(hs_td2)) not like '.' -- can not be only .
and LTRIM(RTRIM(hs_td2)) not like '-' -- can not be only -
and isnumeric(LTRIM(RTRIM(hs_td2))) = 1
THEN CAST(LTRIM(RTRIM(hs_td2)) AS float)
ELSE NULL
END
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.