Преобразование не удалось при преобразовании значения varchar '.' к типу данных int - PullRequest
0 голосов
/ 13 марта 2020

У меня есть запрос, как показано ниже:

SELECT activity_code, 
       activity_name, 
       Count(*) 
       Total_Response, 
       yearnumber, 
       Cast(Avg(Cast(Isnull([response], 0) AS NUMERIC)) AS DECIMAL(10, 2)) 
       [Ratings] 
FROM   (SELECT code         [Activity_Code], 
               activityname [Activity_Name], 
               enddt.yearnumber, 
               CASE 
                 WHEN Isnumeric(asmt.userresponse) = 1 THEN asmt.userresponse 
                 ELSE 0 
               END          [Response] 
        FROM   (SELECT userid, 
                       questionid, 
                       activityid, 
                       attemptenddateid, 
                       CASE 
                         WHEN Isnumeric(userresponse) = 1 THEN userresponse 
                         ELSE '0' 
                       END AS UserResponse 
                FROM   factassessment) asmt 
               INNER JOIN dimuser usr 
                       ON usr.id = asmt.userid 
               INNER JOIN (SELECT 
                                               id, 
                                  Cast(questionidentifier AS VARCHAR(1000)) AS 
                                               QuestionIdentifier 
                           FROM   dimquestion) ques 
                       ON ques.id = asmt.questionid 
               INNER JOIN dimactivity act 
                       ON act.id = asmt.activityid 
               INNER JOIN dimdate enddt 
                       ON enddt.dateid = asmt.attemptenddateid 
        WHERE  ( act.code LIKE 'U-%' 
                  OR act.code LIKE 'CC-%' ) 
               AND usr.empcntry <> 'administrator' 
               AND enddt.yearnumber IN ( 2015, 2016, 2017, 2018, 
                                         2019, 2020, 2021, 2021, 2022 ) 
               AND ques.questionidentifier = 'course_content' 
               AND asmt.userresponse NOT IN ( '0', '-1' )) tab 
GROUP  BY activity_code, 
          activity_name, 
          yearnumber 
ORDER  BY activity_code 

При выполнении кода выше, я получаю следующую ошибку:

[SQLServer] Преобразование не удалось при преобразовании varchar ценность '.' к типу данных int.

Я попытался исправить это, как показано ниже, но все еще получаю ту же ошибку:

SELECT activity_code, 
       activity_name, 
       Count(*) 
       Total_Response, 
       yearnumber, 
       Cast(Avg(Cast(Isnull([response], 0) AS NUMERIC)) AS DECIMAL(10, 2)) 
       [Ratings] 
FROM   (SELECT code         [Activity_Code], 
               activityname [Activity_Name], 
               enddt.yearnumber, 
               CASE 
                 WHEN Isnumeric(asmt.userresponse + 'e0') = 1 THEN 
                 asmt.userresponse 
                 ELSE 0 
               END          [Response] 
        FROM   (SELECT userid, 
                       questionid, 
                       activityid, 
                       attemptenddateid, 
                       CASE 
                         WHEN Isnumeric(userresponse + 'e0') = 1 THEN 
                         userresponse 
                         ELSE '0' 
                       END AS UserResponse 
                FROM   factassessment) asmt 
               INNER JOIN dimuser usr 
                       ON usr.id = asmt.userid 
               INNER JOIN (SELECT 
                                               id, 
                                  Cast(questionidentifier AS VARCHAR(1000)) AS 
                                               QuestionIdentifier 
                           FROM   dimquestion) ques 
                       ON ques.id = asmt.questionid 
               INNER JOIN dimactivity act 
                       ON act.id = asmt.activityid 
               INNER JOIN dimdate enddt 
                       ON enddt.dateid = asmt.attemptenddateid 
        WHERE  ( act.code LIKE 'U-%' 
                  OR act.code LIKE 'CC-%' ) 
               AND usr.empcntry <> 'administrator' 
               AND enddt.yearnumber IN ( 2015, 2016, 2017, 2018, 
                                         2019, 2020, 2021, 2021, 2022 ) 
               AND ques.questionidentifier = 'course_content' 
               AND asmt.userresponse NOT IN ( '0', '-1' )) tab 
GROUP  BY activity_code, 
          activity_name, 
          yearnumber 
ORDER  BY activity_code 


Я все еще получаю ту же ошибку. Помогите решить эту ошибку преобразования.

1 Ответ

0 голосов
/ 13 марта 2020

Если я правильно понимаю этот вопрос, причину этой ошибки можно упростить до следующего утверждения, которое возвращает Conversion failed when converting the varchar value '.' to data type int. error:

SELECT CASE WHEN ISNUMERIC(asmt.UserResponse) = 1 THEN asmt.UserResponse else 0 END [Response]
FROM (
    SELECT CASE WHEN ISNUMERIC('.') = 1 THEN '.' ELSE '0' END AS UserResponse
) asmt

Хорошо бы рассмотреть следующее:

  • Результатом ISNUMERIC('.') является 1, а результатом внутреннего CASE является текст .. Но внешний CASE терпит неудачу, потому что возвращаемый тип из оператора CASE является наивысшим типом приоритета из набора типов в выражениях результата, поэтому в этом случае . неявно преобразуется в int.
  • Не доверяйте функции ISNUMERIC(). Используйте TRY_CONVERT() вместо

Вы можете попробовать использовать следующий подход для решения этой ошибки:

SELECT 
   CASE 
       WHEN TRY_CONVERT(int, asmt.UserResponse) IS NOT NULL THEN TRY_CONVERT(int, asmt.UserResponse) 
       ELSE 0 
   END [Response]
FROM (
    SELECT 
       CASE 
          WHEN TRY_CONVERT(int, '.') IS NOT NULL THEN TRY_CONVERT(int, '.') 
          ELSE 0 
       END AS UserResponse
) asmt
...