2009-08-04 59 views
1

我在一个旧的SQL 2000数据库中有一个存储过程,它将一个格式化为varchar的注释列作为一个货币对象导出。在建立这个表格结构时,人们认为这将是唯一进入该领域的数据。目前的程序功能简单,就是这样的:如何在SQL 2000中TryParse?

SELECT CAST(dbo.member_category_assign.coment AS money) 
    FROM dbo.member_category_assign 
WHERE member_id = @intMemberId 
     AND 
     dbo.member_category_assign.eff_date <= @dtmEndDate 
     AND 
     (
     dbo.member_category_assign.term_date >= @dtmBeginDate 
     OR 
     dbo.member_category_assign.term_date Is Null 
     ) 

然而,数据现在被插入到该列是不能分析的货币对象,并导致程序崩溃。我无法删除“坏”数据(因为这是第三方产品),但需要更新存储过程以测试金钱可分析条目并返回该数据。

如何更新此过程,以便它只返回可作为货币对象解析的值?我是否创建临时表并遍历每个项目,还是有更聪明的方法来做到这一点?我坚持使用传统的SQL 2000(6.0版),因此不幸的是使用任何新功能都不可用。

回答

7

检查IsNumeric可能会对您有所帮助 - 您可以简单地返回零值。如果你想返回'N/a'或其他字符串值

我使用查询中的列创建了下面的示例。

第一个查询只是返回所有行。

第二个查询返回一个MONEY值。

第三个用N/A代替非整数值返回一个String值。

set nocount on 
drop table #MoneyTest 
create table #MoneyTest 
(
    MoneyTestId Int Identity (1, 1), 
    coment varchar (100), 
    member_id int, 
    eff_date datetime, 
    term_date datetime 
) 
insert into #MoneyTest (coment, member_id, eff_date, term_date) 
values 
    (104, 1, '1/1/2008', '1/1/2009'), 
    (200, 1, '1/1/2008', '1/1/2009'), 
    (322, 1, '1/1/2008', '1/1/2009'), 
    (120, 1, '1/1/2008', '1/1/2009') 

insert into #MoneyTest (coment, member_id, eff_date, term_date) 
values ('XX', 1, '1/1/2008', '1/1/2009') 

Select * 
FROM #MoneyTest 

declare @intMemberId int = 1 
declare @dtmBeginDate DateTime = '1/1/2008' 
declare @dtmEndDate DateTime = '1/1/2009' 

SELECT 
    CASE WHEN ISNUMERIC (Coment)=1 THEN CAST(#MoneyTest.coment AS money) ELSE cast (0 as money) END MoneyValue 
FROM #MoneyTest 
WHERE member_id = @intMemberId 
AND #MoneyTest.eff_date <= @dtmEndDate 
AND 
(
    #MoneyTest.term_date >= @dtmBeginDate 
    OR 
    #MoneyTest.term_date Is Null 
) 

SELECT 
    CASE WHEN ISNUMERIC (Coment)=1 THEN CAST (CAST(#MoneyTest.coment AS money) AS VARCHAR) ELSE 'N/a' END StringValue 
FROM #MoneyTest 
WHERE member_id = @intMemberId 
AND #MoneyTest.eff_date <= @dtmEndDate 
AND 
(
    #MoneyTest.term_date >= @dtmBeginDate 
    OR 
    #MoneyTest.term_date Is Null 
) 
+0

美丽!像魅力一样工作!非常感谢! – 2009-08-04 15:59:26

2

道歉为做出新的答案,评论就足够了,但我缺乏必要的权限这样做。在回答你的问题之前,我只想补充一点,你应该谨慎使用上述的ISNUMERIC。虽然它的工作方式和预期的一样,但它也会将“1.3E-2”这样的值解析为一个数值,奇怪的是,您不能在不产生异常的情况下投入数值或金钱。我通常最终使用:

SELECT 
    CASE WHEN ISNUMERIC(some_value) = 1 AND CHARINDEX('E', Upper(some_value)) = 0 
     THEN Cast(some_value as money) 
     ELSE Cast(0 as money) 
    END as money_value