错误:使用SQL中的Hashbytes函数将数据类型varchar转换为numeric时出错

时间:2015-03-22 23:21:31

标签: sql sql-server hash ssis case

我有一个需要更新的旧SSIS包。具体来说,它只用于添加新记录,现在必须根据需要更新和结束日期或删除记录。包中的其他地方我一直在使用Hashbytes函数非常成功地通过从两个数据库中获取匹配的数据集来评估哪些行需要更新,然后将它们作为条件拆分的一部分进行比较。我在源查询中围绕case语句的问题是:

SELECT DISTINCT
DTBL_STUDENTS.STUDENT_ID,
FTBL_TEST_SCORES.TEST_STUDENT_GRADE,
DTBL_TESTS.TEST_NAME,
DTBL_SCHOOL_DATES.DATE_VALUE AS Assessment_Date,
DTBL_SCHOOL_DATES.SIS_SCHOOL_YEAR AS Assessment_Year,
left( CASE
    WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT = 'NA'
    THEN CASE
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'INTE' THEN 'High'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'STRA' THEN 'Some'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'BNCH' THEN 'Low'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT IN ('High', 'Some', 'Low') THEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT
             ELSE FTBL_TEST_SCORES.TEST_SCORE_TEXT
         END
    ELSE CASE
             WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT LIKE '%.0000'
             THEN REPLACE(FTBL_TEST_SCORES.TEST_SCORE_TEXT, '.0000', '')
             ELSE FTBL_TEST_SCORES.TEST_SCORE_TEXT
         END
END,12) AS TEST_SCORE_TEXT,
CASE
    WHEN FTBL_TEST_SCORES.TEST_SCORE_TEXT = 'NA'
    THEN CASE
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'INTE' THEN '1'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'STRA' THEN '3'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT_CODE = 'BNCH' THEN '4'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'High' THEN '1'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'Some' THEN '3'
             WHEN FTBL_TEST_SCORES.TEST_PRIMARY_RESULT = 'Low'  THEN '4'
             ELSE '0'
         END
    ELSE FTBL_TEST_SCORES.TEST_SCORE_VALUE
END AS TEST_SCORE_VALUE,
FTBL_TEST_SCORES.TEST_PERCENTILE_SCORE,
DTBL_SCHOOLS.SCHOOL_HR_ID
FROM K12INTEL_DW.DTBL_TESTS
JOIN K12INTEL_DW.FTBL_TEST_SCORES  ON FTBL_TEST_SCORES.TESTS_KEY         =     
DTBL_TESTS.TESTS_KEY
JOIN K12INTEL_DW.DTBL_SCHOOL_DATES ON DTBL_SCHOOL_DATES.SCHOOL_DATES_KEY =   
FTBL_TEST_SCORES.SCHOOL_DATES_KEY
JOIN K12INTEL_DW.DTBL_STUDENTS     ON DTBL_STUDENTS.STUDENT_KEY          =   
FTBL_TEST_SCORES.STUDENT_KEY
JOIN K12INTEL_DW.DTBL_SCHOOLS      ON DTBL_SCHOOLS.SCHOOL_KEY            = 
FTBL_TEST_SCORES.SCHOOL_KEY
WHERE DTBL_SCHOOL_DATES.SIS_SCHOOL_YEAR = 2014 
AND DTBL_STUDENTS.STUDENT_CURRENT_DISTRICT_CODE = '2180'
AND FTBL_TEST_SCORES.TEST_STUDENT_GRADE IN ('PS', 'PK', 'KG', '01', '02',  
'03', '04', '05', '06', '07', '08')
AND DTBL_TESTS.TEST_VENDOR IS NOT NULL
AND FTBL_TEST_SCORES.TEST_HIGHEST_SCORE_INDICATOR IN ('Yes', '--')

我需要哈希进行比较的3个值是: TEST_SCORE_TEXT TEST_SCORE_VALUE Assessment_Date

它似乎在函数中的TEST_SCORE_VALUE上窒息:

   HASHBYTES('SHA1',ISNULL(#Dware.TEST_SCORE_TEXT,'')+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,''))+convert(varchar(50),(ISNULL(Assessment_Date,'')))) as SourceHash

这是我收到错误的地方"将数据类型varchar转换为数字"时出错。我尝试将源查询放入子查询并从该源查询中执行select *,(function)。我已经尝试将case语句放入hashbytes函数中,并且我尝试使用临时表。我的假设是,它获得的是基础价值,而不是案例陈述产生的价值,但我不知道为什么,或者如何解决它,以便我得到我期待的数值/缺憾。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

假设FTBL_TEST_SCORES.TEST_SCORE_VALUE是数字,请查看创建CASE的{​​{1}}语句。您可以通过评估TEST_SCORE_VALUETEST_PRIMARY_RESULT_CODE等来创建字符串,但最终的TEST_PRIMARY_RESULT语句可能会返回一个数值(ELSE)。

我相信Sql Server通过最后一个返回值确定FTBL_TEST_SCORES.TEST_SCORE_VALUE语句的输出类型。 (在任何情况下,它都有一个算法,用于在混合单个CASE语句时确定返回类型。)

因此,它会将THEN语句视为键入任何CASE,这可能与FTBL_TEST_SCORES.TEST_SCORE_VALUE语句的早期varchar返回值不一致。

修复此问题,CASE函数应该可以正常工作。

答案 1 :(得分:0)

+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,''))

原来应该是:

+convert(varchar(10),ISNULL(TEST_SCORE_VALUE,0))

然后一切正常。