【问题标题】:Conversion failed error with dynamic SQL query动态 SQL 查询的转换失败错误
【发布时间】:2012-12-11 01:53:48
【问题描述】:

下面的查询抛出这个错误:

Conversion failed when converting the varchar value 'query below that stops at WHERE tsv.Transition_ID =' to data type int

DECLARE @Language_ID INT
SELECT @Language_ID = dbo.BPE_F_Default_Language_GetOne()

DECLARE @Transition_ID int
SET @Transition_ID = -1

DECLARE @SQLSTR nvarchar(4000)
SELECT @SQLSTR = 'SELECT tsv.Transition_Set_Variable_ID
                        , tsv.Set_To_Variable_ID
                        , tsv.Transition_ID
                        , tl.Transition_Text
                        , tsv.Variable_ID_To_Change
                        , variable.Name
                        , tsv.Set_To_Variable_ID
                        , tsv.Set_To_Value_ID
                        , tsv.Changed_In_SP
                        , tsv.Set_To_Comment_Input
                        , tsv.Comment AS Assigned_Comment
                        , variable2.Name AS Set_To_Variable_Name
                        , value.Name AS Set_To_Value_Name
                        FROM BPE_T_VA_Variable AS variable 
                        INNER JOIN BPE_T_VA_Transition_Set_Variable AS tsv 
                            ON variable.Variable_ID = tsv.Variable_ID_To_Change
                        LEFT JOIN BPE_T_VA_Variable AS variable2 
                            ON tsv.Set_To_Variable_ID = variable2.Variable_ID
                        LEFT JOIN BPE_T_VA_Value AS value 
                            ON tsv.Set_To_Value_ID = value.Value_ID
                        INNER JOIN BPE_T_WF_Transition_Localisation AS tl
                            ON tsv.Transition_ID = tl.WF_Transition_ID
                        WHERE tsv.Transition_ID = ' + @Transition_ID + ' OR ' + @Transition_ID + ' = -1 
                        AND (' + @Column + ' LIKE ''%''' + @search_string + '''%'' )
                        AND tl.Language_ID = ' + @Language_ID + '
                        ORDER BY tsv.Transition_ID, variable.Name'
EXEC(@SQLSTR);

有人知道这是什么吗?

【问题讨论】:

  • 如果你在exec之前打印@SQLSTR的值,你能把结果贴出来吗?

标签: sql sql-server


【解决方案1】:

@Transition_IDINT,您必须先将其转换为 VARCHAR,然后再将其与字符串的其余部分连接。

但是,最好使用sp_executeSql,并在查询中参数化@Transition_ID@search_string 参数。就目前而言,它很可能容易受到Sql Injection Attack 的攻击。

此外,要非常小心你允许进入@Column 的值,最好使用白名单,因为这不能以你使用它的方式进行参数化,而且它也会让你容易受到攻击.

【讨论】:

    【解决方案2】:

    由于您将INT 连接到一个字符串,您必须对其进行转换,否则会引发错误。

    添加以下内容:

    cast(@Transition_ID as varchar(50))
    

    制作完整的脚本:

    DECLARE @Language_ID INT
    SELECT @Language_ID = dbo.BPE_F_Default_Language_GetOne()
    
    DECLARE @Transition_ID int
    SET @Transition_ID = -1
    
    DECLARE @SQLSTR nvarchar(4000)
    SELECT @SQLSTR = 'SELECT tsv.Transition_Set_Variable_ID
                            , tsv.Set_To_Variable_ID
                            , tsv.Transition_ID
                            , tl.Transition_Text
                            , tsv.Variable_ID_To_Change
                            , variable.Name
                            , tsv.Set_To_Variable_ID
                            , tsv.Set_To_Value_ID
                            , tsv.Changed_In_SP
                            , tsv.Set_To_Comment_Input
                            , tsv.Comment AS Assigned_Comment
                            , variable2.Name AS Set_To_Variable_Name
                            , value.Name AS Set_To_Value_Name
                            FROM BPE_T_VA_Variable AS variable 
                            INNER JOIN BPE_T_VA_Transition_Set_Variable AS tsv 
                                ON variable.Variable_ID = tsv.Variable_ID_To_Change
                            LEFT JOIN BPE_T_VA_Variable AS variable2 
                                ON tsv.Set_To_Variable_ID = variable2.Variable_ID
                            LEFT JOIN BPE_T_VA_Value AS value 
                                ON tsv.Set_To_Value_ID = value.Value_ID
                            INNER JOIN BPE_T_WF_Transition_Localisation AS tl
                                ON tsv.Transition_ID = tl.WF_Transition_ID
                            WHERE tsv.Transition_ID = ' + cast(@Transition_ID as varchar(50)) + ' OR ' + cast(@Transition_ID as varchar(50)) + ' = -1 
                            AND (' + @Column + ' LIKE ''%''' + @search_string + '''%'' )
                            AND tl.Language_ID = ' + @Language_ID + '
                            ORDER BY tsv.Transition_ID, variable.Name'
    EXEC(@SQLSTR);
    

    【讨论】:

      【解决方案3】:

      将您的 Int 变量转换为 varchar:

      SELECT @SQLSTR = 'SELECT tsv.Transition_Set_Variable_ID
                              , tsv.Set_To_Variable_ID
                              , tsv.Transition_ID
                              , tl.Transition_Text
                              , tsv.Variable_ID_To_Change
                              , variable.Name
                              , tsv.Set_To_Variable_ID
                              , tsv.Set_To_Value_ID
                              , tsv.Changed_In_SP
                              , tsv.Set_To_Comment_Input
                              , tsv.Comment AS Assigned_Comment
                              , variable2.Name AS Set_To_Variable_Name
                              , value.Name AS Set_To_Value_Name
                              FROM BPE_T_VA_Variable AS variable 
                              INNER JOIN BPE_T_VA_Transition_Set_Variable AS tsv 
                                  ON variable.Variable_ID = tsv.Variable_ID_To_Change
                              LEFT JOIN BPE_T_VA_Variable AS variable2 
                                  ON tsv.Set_To_Variable_ID = variable2.Variable_ID
                              LEFT JOIN BPE_T_VA_Value AS value 
                                  ON tsv.Set_To_Value_ID = value.Value_ID
                              INNER JOIN BPE_T_WF_Transition_Localisation AS tl
                                  ON tsv.Transition_ID = tl.WF_Transition_ID
                              WHERE tsv.Transition_ID = ' + cast(@Transition_ID as varchar) + ' OR ' + cast(@Transition_ID as varchar) + ' = -1 
                              AND (' + @Column + ' LIKE ''%''' + @search_string + '''%'' )
                              AND tl.Language_ID = ' + cast(@Language_ID as varchar) + '
                              ORDER BY tsv.Transition_ID, variable.Name'
      

      【讨论】:

        【解决方案4】:

        这不会给你带来麻烦吗?

        WHERE tsv.Transition_ID = ' + @Transition_ID + ' OR ' + @Transition_ID + ' = -1
        

        我认为它必须是

        WHERE tsv.Transition_ID = ' + @Transition_ID + ' OR tsv.Transition_ID =' + @Transition_ID + ' = -1
        

        由于您将值设置为 -1,我希望 SQL(如果您打印它)看起来像:

        WHERE tsv.Transition_ID = -1 OR -1 = -1
        

        这是故意的吗?

        【讨论】:

        • 我认为这将是一个逻辑错误,而不是转换错误。我的猜测是查询在这方面是正确的,因为-1 的值可能用于包含所有值,如果参数使用此特殊值,则不会按tsv.Transition_ID 过滤。
        • 是的,这将是一个不同的错误,这就是为什么我预计它会导致问题,尽管可能在他解决了这个问题之后。即使@transition_id = -1 表示“全选,对此字段没有限制”,他仍在构建要执行的字符串文字,它必须是有效的 SQL。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-02
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-24
        相关资源
        最近更新 更多