使用动态查询更新表

时间:2014-06-11 15:39:37

标签: sql-server

SET @TempTable = 'UPDATE #TempTable SET AvgVal = ' + @AvgVal + '
WHERE PropertyName =''' + @PropertyName + '''' +  ' AND CrudeName =''' +  @crudeName + ''''

我有一个动态的更新查询。 AvgVal是浮动的。该变量在表中也具有相同的数据类型。我仍然得到一个错误 - 将数据类型varchar转换为数字时出错。 如果我将值转换为varchar它的工作原理。什么是解决方法。

3 个答案:

答案 0 :(得分:0)

我明白了。对不起,被误解了。

是的,因为SQL Server的工作方式。您正在构建连接字符串。你将不得不做CAST。 SQL Server中的类型转换有点不稳定。您会认为它本身会转换为最简单的数据类型varchar,但在这种情况下它不是。所以你必须做... + CAST(@AvgVal AS VARCHAR(255))+ ...

答案 1 :(得分:0)

请记住有时像@PropertyName这样的变量,如果你应该做Nvarchar类型

在字符串N'

前面

DECLARE @TempTable NVARCHAR

SET @TempTable = N'UPDATE等等,其余为

答案 2 :(得分:0)

你称之为"解决方法"是答案。 SQL Server使用+运算符作为加法和字符串连接。但是,因为加法运算符的优先级略高于连接运算符,所以假定加法运算符首先应用。

请参阅Operator Precedence上的SQL Server BOL。在第3级优先级,顺序为:

+ (Positive)
- (Negative)
+ (Add)
+ (Concatenate)
- (Subtract)
& (Bitwise AND),
^ (Bitwise Exclusive OR)
| (Bitwise OR)

要了解这会如​​何影响查询,请执行以下示例:

select '1' + 2

此查询的结果不是错误。 SQL Server将+解释为添加。它看到数字2是一个整数,所以它试图转换字符串' 1'成一个整数并成功。结果是整数3。

然而,试试这个:

select '1.0' + 2

SQL Server再次将此视为一个补充,注意2是一个整数,并尝试转换字符串' 1.0'成一个整数。此转换失败,并显示以下错误:

  

Msg 245,Level 16,State 1,Line 1转换时转换失败   varchar值' 1.0'数据类型int。

在您的示例中,SQL Server检测到float @AvgVal并尝试转换字符串' UPDATE #TempTable SET AvgVal ='进入一个浮子。转换失败非常严重,并且您报告的错误发生了。

一种可能性是首先将@AvgVal转换为字符串:

SET @TempTable = 'UPDATE #TempTable
    SET AvgVal = ' + CAST(@AvgVal AS VARCHAR) + '
    WHERE PropertyName =''' + @PropertyName + '''' +  '
    AND CrudeName =''' +  @crudeName + '''

注意:此查询容易受到SQL injection attack的攻击!为避免SQL注入攻击,请始终将数据作为参数传递给动态查询:

SET @TempTable = N'UPDATE #TempTable SET AvgVal = @AvgVal
WHERE PropertyName = @PropertyName AND CrudeName = @crudeName'
exec sp_executesql @TempTable,
    N'@AvgVal float, @PropertyName varchar(255), @crudeName varchar(255)',
    @PropertyName = @PropertyName,
    @CrudeName = @crudeName

这样可以避免SQL注入攻击并避免转换错误。