INT字段 - 字符串或二进制数据将被截断

时间:2014-03-06 09:23:45

标签: sql sql-server-2008

第一次发布海报,长期粉丝。 我已经查看了关于这个主题的所有其他答案,找不到任何解决问题的方法。

我有一些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  

1 个答案:

答案 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

     

转换nvarchar值时转换失败'这是对数据类型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以使其进入查询并允许更好的查询计划缓存。