簡體   English   中英

如何在SQL Server 2008中將varchar(4)轉換為float?

[英]How to convert varchar(4) to float in SQL Server 2008?

我正在嘗試將我的數據庫字段從VARCHAR(4)FLOAT 這些字段中的某些值可能不是數字,因為這些字段之前沒有任何驗證。 我的主要目標是以float格式轉換任何integerdecimal值並保存在新數據庫字段中。 對於這個過程,我使用舊表中的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.

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