在括号中将Varchar转换为负十进制

时间:2018-01-15 07:38:03

标签: sql-server tsql sql-server-2012

我想将String更改为负十进制值。该字符串采用以下格式: ($421.24)

我想将此Varchar更改为decimal,以显示-421.24(421.24)。 我正在使用Replace函数来实现这一目标,但这不是一个很酷的方式:

Select convert(decimal(18,2), Replace(Replace(Replace('($421.24)','$', '' ),'(','-'),')','')) -- output -421.24

我想让它成为一个普通的sql staement,它对正数和负数都适用。请建议。

2 个答案:

答案 0 :(得分:1)

以下是一些较短的选项:

  1. 使用一次替换即可一次性替换($符号:
    Select CAST(Replace(Replace('($421.24)','($', '-'), ')', '') As decimal(18,2))

  2. 使用substring而不是replace:
    Select CAST('-' + SUBSTRING('($421.24)',3, LEN('($421.24)') - 3) As decimal(18,2))

  3. 对于SQL Server 2017或更高版本,您可以使用translate替换单个命令中的多个字符:
    Select CAST(TRANSLATE('($421.24)', '($)', ' - ') As decimal(18,2))

答案 1 :(得分:0)

获取字符串并使用WHILE循环,取出每个字符并检查它是.还是数字。如果是,则取该字符,否则忽略它,最后将其转换为十进制值。

<强>查询

declare @str as varchar(100) = '($421.24)';
declare @len as int;
select @len = len(@str);
declare @i as int;
set @i = 1;
declare @res as varchar(100) = '';
while(@i <= @len)
begin
    declare @c as char(1);
    select @c = substring(@str, @i, 1);
    select @res+= case when ASCII(@c) = 46 or (ASCII(@c) between 48 and 57)
      then @c else '' end;

    set @i += 1;
end

select cast(@res as decimal(18, 2)) as [decimal_val];

<强> Find a demo here

注意:您可能需要检查多个点。

<强>更新

如果字符串的格式不能转换为十进制值,则在WHILE循环后添加以下内容。

<强>查询

declare @isnum as bit;
select @isnum = isnumeric(@res);
if(@isnum = 1)
    select cast(@res as decimal(18, 2));
else 
    select 'String cannot convert to a decimal value.';

<强> An other demo