2014-03-06 78 views
0

第一次海报,长时间的粉丝。 我已经看过关于此主题的所有其他答案,找不到解决问题的任何内容。INT字段 - 字符串或二进制数据将被截断

我有一些SQL按区域使用动态数据透视返回资格矩阵。我的代码工作正常,带回所有行,但现在我想使用过滤器。

出错的代码是在WHERE子句中:T3.TrainingTypeID = ' + @TrainingID + ' 如果我硬编码为T3.TrainingTypeID值(这是tlkpTrainingType.ID的别名),(200,说),我得到一个返回行,这是我想要的,但如果我将相同的值赋给变量@TrainingID INT,我会得到上述错误信息。 我检查了tlkpTrainingType.ID的数据类型,它绝对是INT(并且Select Max(Len(TlkpTrainingType.ID)) From TlkpTrainingType返回3)。

我不确定我是否理解触发器的一切,但鉴于我只是从数据库中读取数据,我是否认为它在这里不相关?

我错过了一些完全明显的东西吗? 所有的见解都表示赞赏,我是一个相对的新手!

这里是我的代码,相关的WHERE子句是靠近底部:

DECLARE @TrainingID AS INT, @cols AS NVARCHAR(MAX), @cols2 AS NVARCHAR(MAX), @cols3 AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) 

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(tlkpRegion.RegionName) 
      FROM tlkpRegion FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
     ,1,1,''); 

SET @cols2 = STUFF((SELECT distinct ', ISNULL(' + QUOTENAME(tlkpRegion.RegionName) + ',0) as' + QUOTENAME(tlkpRegion.RegionName)  FROM tlkpRegion FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
     ,1,1,''); 

SET @cols3 = STUFF((SELECT distinct ', SUM(' + QUOTENAME(tlkpRegion.RegionName) + ') as ' + QUOTENAME(tlkpRegion.RegionName)  FROM tlkpRegion FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') 
     ,1,1,''); 

SET @TrainingID = 200; 

SET @query = ' 

SELECT 
    T3.TrainingType, 
    T3.TrainingTypeID, 
    ' + @cols3 + ' 

    FROM 

     (SELECT 
     tlkpTrainingType.Name AS TrainingType, 
     tlkpTrainingType.ID AS TrainingTypeID, ' + @cols2 + ' 

     FROM 
     tlkpTrainingType 
      LEFT OUTER JOIN 

      (SELECT 
      TrainingType, 
      TrainingTypeID, ' + @cols + ' 

      FROM 

       (SELECT 
       R0.RegionID, 
       R0.RegionName, 
       T0.TrainingType, 
       T0.TrainingTypeID, 
       T0.CountQuals 

       FROM 

        tlkpRegion AS R0 

        LEFT OUTER JOIN 

        (SELECT   
         tlkpTrainingType.Name AS TrainingType, 
         tlkpTrainingType.ID AS TrainingTypeID, 
         tlkpTrainingType.ID AS CountQuals, 
         tlkpRegion.RegionName, 
         tlkpRegion.RegionID 

         FROM    

         tblTechnicianTraining 
         INNER JOIN tlkpTrainingType ON tlkpTrainingType.ID = tblTechnicianTraining.TrainingTypeRef 
         LEFT OUTER JOIN tblTechnician ON tblTechnician.TechnicianID = tblTechnicianTraining.TechnicianRef 
         INNER JOIN tlkpRegion ON tlkpRegion.RegionID = tblTechnician.RegionRef 

         WHERE 

         tlkpTrainingType.Deleted = 0 AND 
         tblTechnician.CurrentlyEmployed = 1 AND 
         tblTechnicianTraining.ExpiryDate > GetDate() 
        ) AS T0 
        ON T0.RegionID = R0.RegionID 
       ) 
       AS T1 

       PIVOT 

       (COUNT(CountQuals) 
        for RegionName IN (' + @cols + ') 
       ) AS P 

      GROUP BY 
      TrainingType, 
      TrainingTypeID, ' + @cols + ') AS T2 
      ON T2.TrainingTypeID = tlkpTrainingType.ID 
      ) AS T3 

     WHERE T3.TrainingTypeID = ' + @TrainingID + ' 

     GROUP BY 
     T3.TrainingType, 
     T3.TrainingTypeID    
       ' 

EXECUTE (@query) 

这里是结果,我的例子后:

TrainingType ¦ TrainingTypeID ¦ CAD ¦ CSD ¦ DVT ¦ FIN ¦ ITS ¦ IWK 

HedgeCutter ¦  200  ¦ 0 ¦ 2 ¦ 0 ¦ 7 ¦ 1 ¦ 0 
+0

如果您想获得答案,请尽量让您的问题易于阅读。周围的人应该花时间解决问题,而不是努力阅读。谢谢 –

回答

1

我很惊讶这个作品因为你连接了一个INT变量和一个NVARCHAR(MAX)变量,例如如果我运行:

DECLARE @i INT = 0, 
     @n NVARCHAR(MAX); 

SET @n = N'This is a test' + @i; 

我得到的错误:

Msg 245, Level 16, State 1, Line 4

Conversion failed when converting the nvarchar value 'This is a test' to data type int.

为了应用,你可能是最好关闭用sp_executesql与参数一起,而不是连接你的价值和使用EXEC过滤器:

所以不是:

SET @Query = '.... 
     WHERE T3.TrainingTypeID = ' + @TrainingID + ' 
     ...' 
EXEC (@Query); 

你可以使用:

SET @Query = '.... 
     WHERE T3.TrainingTypeID = @TrainingID 
     ...'; 

EXECUTE sp_executesql @Query, N'@TrainingID INT', @TrainingID; 

这是更类型安全,意味着你不必投你的INT变量为nvarchar,让他们到查询,并允许更好的查询计划缓存太。

+0

@ GarethD:它的工作原本是因为没有过滤器,即它全部是NVARCHAR(MAX),根本没有@TrainingID。但是,这很好,最重要的是,我明白为什么 - 谢谢GarethD! – Indigofish

+0

对于格式化人员不够清晰的抱歉 - 只需掌握发布ona编码网站即可。不过,再次感谢。 – Indigofish

相关问题