SQL Server内联视图错误?

时间:2015-09-03 18:20:17

标签: sql-server

我正在使用SQL Server 2012并且我认为内联视图是一个非常奇怪的问题。

首先,我有这个问题:

select 
    parcelnumber, 
    sectionname,
    value.Value CalculatedValue,
    overriddenvalue.Value OverriddenValue,
    homk.Value CalculatedHomeownersValue,
    cv.CharacteristicValue,
    pdt.PropertyDataTypeID
from landsections ls
join lands l 
  on ls.landid = ls.landid
join parcels p
  on l.ParcelID = p.ParcelID
join CharacteristicValueGroups cvg
  on cvg.ParcelObjectID = ls.ParcelObjectID
join CharacteristicValues cv 
  on cvg.CharacteristicValueGroupID = cv.CharacteristicValueGroupID
join Characteristics c
  on cv.CharacteristicID = c.CharacteristicID
join CharacteristicDetails cd
  on c.CharacteristicDetailsID = cd.CharacteristicDetailsID
 and cd.name = '09 Composite Adjustment'
join PropertyDataTypes pdt
  on cv.PropertyDataTypeID = pdt.PropertyDataTypeID
 and pdt.Label = 'Type'
join parcelobjectvalues value
  on value.ParcelObjectID = ls.ParcelObjectID
 and value.valuetype = 'CalculatedAdjustedValue'
left join parcelobjectvalues overriddenvalue
  on overriddenvalue.ParcelObjectID = ls.ParcelObjectID
 and overriddenvalue.valuetype = 'OverriddenValue'
join parcelobjectvalues homk
  on homk.ParcelObjectID = ls.ParcelObjectID
 and homk.valuetype = 'CalculatedHomeownersValue'
where year(appraisaldate) = 2016
  and CharacteristicValue like '%F%'

注意where子句中的最后一项。此查询返回0结果,这应该证明没有包含F的CharacteristicValue列的行。

现在让我们运行此查询:

select *
from
(
    select 
        *,
        case 
            when CharacteristicValue like '%A' then convert(int, substring(characteristicvalue, 1, len(characteristicvalue) - 1))
            when CharacteristicValue like '%K' then convert(int, substring(characteristicvalue, 1, len(characteristicvalue) - 1))
            when isnumeric(CharacteristicValue) = 1 then convert(int, characteristicvalue)
            else 0
        end Quantity
    from
    (
        select 
            parcelnumber, 
            sectionname,
            value.Value CalculatedValue,
            overriddenvalue.Value OverriddenValue,
            homk.Value CalculatedHomeownersValue,
            cv.CharacteristicValue,
            pdt.PropertyDataTypeID
        from
            landsections ls
            join lands l on ls.landid = ls.landid
            join parcels p on l.ParcelID = p.ParcelID
            join CharacteristicValueGroups cvg on cvg.ParcelObjectID = ls.ParcelObjectID
            join CharacteristicValues cv on cvg.CharacteristicValueGroupID = cv.CharacteristicValueGroupID
            join Characteristics c on cv.CharacteristicID = c.CharacteristicID
            join CharacteristicDetails cd on c.CharacteristicDetailsID = cd.CharacteristicDetailsID and cd.name = '09 Composite Adjustment'
            join PropertyDataTypes pdt on cv.PropertyDataTypeID = pdt.PropertyDataTypeID and pdt.Label = 'Type'
            join parcelobjectvalues value on value.ParcelObjectID = ls.ParcelObjectID and value.valuetype = 'CalculatedAdjustedValue'
            left join parcelobjectvalues overriddenvalue on overriddenvalue.ParcelObjectID = ls.ParcelObjectID and overriddenvalue.valuetype = 'OverriddenValue'
            join parcelobjectvalues homk on homk.ParcelObjectID = ls.ParcelObjectID and homk.valuetype = 'CalculatedHomeownersValue'
        where
            year(appraisaldate) = 2016
    ) Tbl
) Tbl2
where
    CharacteristicValue like '%A' and Quantity > 10

请注意,我已删除%F%支票。由于第一个查询证明在CharacteristicValue列中没有带有F的行,我认为外部查询可以依赖于此。

然而,我明白了:

  

转换varchar值时转换失败' F'数据类型int。

我认为这可能发生的唯一方法是忽略pdt.Label = 'Type',但对于我的生活,我无法理解为什么。

2 个答案:

答案 0 :(得分:2)

您的视图会过滤:

where year(appraisaldate) = 2016 and CharacteristicValue like '%F%'

这意味着可以存在仅满足CharacteristicValue like '%F%'的行。

在T-SQL中未指定执行顺序。当试图保护可能会进行一些检查的计算时,这是一个问题。

通常,case ... when是一个可靠的守卫。在我看来,我认为没有理由不这样做。所以你可以做when CharacteristicValue like '%A' and CharacteristicValue not like '%F%'

或者,您可以使用始终安全的TRY_CONVERT

where 不是可靠的后卫。在另一个答案中,你发布了这个有效,但这只是巧合。使用不同的查询计划,这可能会失败。计划的变化有很多原因。

答案 1 :(得分:-1)

答案似乎是由于相关性而无法在外部查询之前执行内部查询。在外部查询中添加过滤器解决了这个问题。