Как мне попробоватьParse в SQL 2000? - PullRequest
1 голос
/ 04 августа 2009

У меня есть хранимая процедура в старой базе данных SQL 2000, которая принимает столбец комментариев, отформатированный как varchar, и экспортирует его как денежный объект. Во время настройки этой структуры таблицы предполагалось, что это будут единственные данные, поступающие в это поле. Текущая процедура функционирует просто так:

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), поэтому, к сожалению, использование любой из более новых функций недоступно.

Ответы [ 2 ]

7 голосов
/ 04 августа 2009

Проверка IsNumeric может вам помочь - вы можете просто вернуть нулевое значение. Если вы хотите вернуть 'N / a' или другое строковое значение

Я создал образец ниже со столбцами из вашего запроса.

Первый запрос просто возвращает все строки.

Второй запрос возвращает значение MONEY.

Третий возвращает значение String с N / A вместо нецелого значения.

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
)
2 голосов
/ 30 мая 2011

Прошу прощения за создание нового ответа, где будет достаточно комментария, но у меня нет необходимых разрешений для этого. К ответу на ваш вопрос я хотел бы только добавить, что вы должны использовать вышеуказанную 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...