2017-05-31 201 views
2

我有一张表,其中一列有数据,如($23,324.09)。如果是$23,324.09,那么我可以将它转换为money,然后是float。但当我尝试时,()正在导致错误。我是否必须将UDF应用于该列或者是否有另一种方法来转换此类值。如何将varchar转换为负数?

注意:我无法控制数据如何到达该表。

回答

1

使用几个replace()

declare @col varchar(32) = '($23,324.09)' 

select convert(decimal(19,4),replace(replace(replace(replace(@col,'(','-'),',',''),')',''),'$','')) 

回报:-23324.0900


运行一个简单的测试,这是在时间为parse()当量约为1 /第三运行。

dbfiddle:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=675f6eb70986bd24880c66a8be4f5cbd


下面是一个使用money数据类型的短替代:

select convert(money,replace(replace(@col,'(','-'),')','')) 

dbfiddle:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=31bfc3e1e48b8f863e89bcef9a6ffddc

+0

如果我是把这个在UDF,将有20000行(或更多)的数据集打交道时,导致一个巨大的性能损失? –

+0

@DaBest 一个标量udf将会降低几乎任何东西的性能,但是一个内联表值函数应该没问题。 - [何时SQL函数不是函数? “如果它不是内联的,那就是垃圾。” - Rob Farley](http://sqlblog.com/blogs/rob_farley/archive/2011/11/08/when-is-a-sql-function-not-a-function.aspx) – SqlZim

+0

@DaBest我加了一个较短的版本使用'money'数据类型。 – SqlZim

7

你也使用PARSETRY_PARSE

SELECT TRY_PARSE('($23,324.09)' AS MONEY USING 'en-US') 

返回

-23324.09 
+1

我错过了'sql-server-2012'标签; +1 – SqlZim