Ошибка преобразования при преобразовании значения varchar 'U' в тип данных int - PullRequest
1 голос
/ 07 января 2020

Я получаю сообщение "Ошибка преобразования varchar в int" для полей Q1_c и Q2_c.

Эти поля имеют значение CHAR(1), а значения этих полей равны 1,2,3 , 4,5 или U, но он не будет преобразован при U, поэтому я пытаюсь изменить значение U на что-то еще, например 0. Я также пробовал CAST(a.q2_c as varchar(1)) = 'U' - но это тоже не работает. Должен ли я использовать INT или VARCHAR()? Я также пытался использовать CONVERT вместо CAST.

ALTER VIEW [dbo].[vCDCP_rptInfantImprove]
as
select distinct
         IND.tb_cdcp_individuals as Individuals_IndividualID 
       , A.[tb_cdcp_individuals] as ATQInfant_IndividualID
       , A.CreateDate as ATQInfant_CreateDate
       , CAST(a.q1_c as varchar(3)) as A_Q1
       , CAST(a.q2_c as varchar(3)) as A_Q2
        ---Infant Sum
       , Sum(isnull(cast(a.Q1_c as int),0)) + Sum(isnull(cast(a.Q2_c as int),0)) as InfantSum
        ---Change U to 0
       , case when CAST(a.q1_c as int) = 'U' then 0 else 0 end as Unknown1
       , case when CAST(a.q2_c as int) = 'U' then 0 else 0 end as Unknown2
from DBO.tb_cdcp_ATQInfant a
left join DBO.tb_cdcp_individuals ind on a.[tb_cdcp_individuals] = ind.[tb_cdcp_individuals]
where ind.agegroup_c = 'C' 
group by IND.tb_cdcp_individuals, A.tb_cdcp_individuals, A.CreateDate   
       ,     a.q1_c
       ,     a.q2_c
GO

Ответы [ 5 ]

1 голос
/ 07 января 2020

Вы можете go об этом несколькими способами:

Поскольку поля имеют символьный формат, замените 'u' на '0', а затем преобразуйте его в int:

CAST(Replace(q1_c,'u','0') as int)

Или, если вы хотите создать новое вычисляемое поле, вы можете напрямую создать целочисленное поле:

Case when q1_c='u' then 0 else CAST(q1_c as int) end as q1_c_calc

Надеюсь, это поможет.

1 голос
/ 07 января 2020

Мне приходит в голову простая идея - определить другую таблицу ... с CHAR(1) для каждого возможного значения и INT для соответствующего числа. Затем просто JOIN к этому столу. Без сомнения, движок SQL просто забросит все это в память, если он будет содержать только 5 строк. Если когда-нибудь нужно будет закодировать больше значений, это легко сделать.

0 голосов
/ 07 января 2020

У вас есть несколько причин, по которым это не сработает:

Прежде всего, вы должны убедиться, что значения, которые вы пытаетесь привести, совместимы с типом, в который вы пытаетесь привести. CAST (a.q1_ c как int) будет нормально работать, когда значение равно 1,2,3,4,5, но не будет работать, если значение равно «U». Если вы уверены, что значения 1,2,3,4,5, или U, вы можете использовать 'case'

CAST(case when a.q1_c = 'U' then 0 else a.q1_c end  as int) = 'U'

, если нет, ISNUMERI C () может работать для этого case.

Также CAST (a.q1_ c как int) = 'U' что вы пытаетесь сделать здесь? Почему не просто a.q1_ c = 'U'?

0 голосов
/ 07 января 2020

Пожалуйста, попробуйте это:

ALTER VIEW [dbo].[vCDCP_rptInfantImprove]
as
select distinct
         IND.tb_cdcp_individuals as Individuals_IndividualID 
       , A.[tb_cdcp_individuals] as ATQInfant_IndividualID
       , A.CreateDate as ATQInfant_CreateDate
       , CAST(a.q1_c as varchar(3)) as A_Q1
       , CAST(a.q2_c as varchar(3)) as A_Q2
        ---Infant Sum

       , Sum(isnull( case when a.Q1_c = 'U' then 0 else cast(a.Q1_c as int) end,  0 )) + Sum(isnull( case when a.Q2_c = 'U' then 0 else cast(a.Q2_c as int) end,  0 )) as InfantSum
        --- Remove cast here and not sure what goes in else part.
       , case when a.q1_c = 'U' then 0 else a.q1_c end as Unknown1
       , case when a.q2_c = 'U' then 0 else a.q2_c end as Unknown2
from DBO.tb_cdcp_ATQInfant a
left join DBO.tb_cdcp_individuals ind on a.[tb_cdcp_individuals] = ind.[tb_cdcp_individuals]
where ind.agegroup_c = 'C' 
group by IND.tb_cdcp_individuals, A.tb_cdcp_individuals, A.CreateDate   
       ,     a.q1_c
       ,     a.q2_c
GO
0 голосов
/ 07 января 2020

Предполагая, что вы не можете ничего сделать для очистки данных, хранящихся в таблицах, или сделать что-либо для управления значениями, вставляемыми в указанные таблицы, вы можете использовать TRY_CONVERT или TRY_CAST. Обе функции возвращают NULL, если CHAR (1) не может преобразоваться в INT. Вы просто проверяете NULL таким образом, что вам не нужно беспокоиться о любых других символах румян, которые могут быть случайно вставлены.

IF OBJECT_ID('tempdb..#sample') IS NOT NULL
    BEGIN
        DROP TABLE #sample
    END
GO
CREATE TABLE #sample
(
    q1_c  CHAR(1),
    q2_c  CHAR(1)
)
INSERT INTO #sample(q1_c , q2_c )
VALUES ('1','1'),('2','2'),('3','3'),('4','4'),('5','5')
       ,('u','U'),('$','$'), ('#','#'), ('^','^'), ('&','&'), ('*','*'),
       ('1','1'),('2','2'),('3','3'),('4','4'),('5','5')

SELECT CASE WHEN TRY_CAST(q1_c AS INT) IS NULL THEN '0' ELSE q1_c END A_Q1, 
       CASE WHEN TRY_CONVERT(INT, q2_c) IS NULL THEN '0' ELSE q2_c END A_Q2,
       SUM(TRY_CAST(q1_c AS INT)) sumQ1_c, SUM(TRY_CONVERT(INT, q2_c)) sumQ2_c
FROM #sample
GROUP BY q1_c, q2_c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...