我只需要批量更新数据。为此,我创建了一个表类型和存储过程。
我用这个创建了类型:
CREATE TYPE [dbo].[ItemsUpdate] AS TABLE
(
[ItemPartNumber] [varchar](100) NULL,
[VendorName] [varchar](100) NULL,
[Price] [varchar](100) NULL
)
GO
我的存储过程是这样的:
ALTER PROCEDURE [dbo].[UpdateItemsByVendorPrice]
@tblItemUpdate ItemsUpdate READONLY
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO Items orgTable
USING @tblItemUpdate typeTable ON orgTable.ItemPartNumber = typeTable.ItemPartNumber
WHEN MATCHED THEN
UPDATE SET orgTable.Price = CONVERT(FLOAT, typeTable.Price);
END
即使我使用了convert(float,typeTable.Price)
,我也遇到了这个错误。
System.Data.dll中出现未处理的“System.Data.SqlClient.SqlException”类型异常
其他信息:将数据类型varchar转换为float
时出错
答案 0 :(得分:1)
UPDATE SET orgTable.Price = convert(float,typeTable.Price);
表示您要将typeTable.Price
的内容转换为浮点数。可能你有不好的数据,不能转换为浮点数,例如“foo”或不正确的本地化数据,如234,457
。
如果您使用的是SQL 2012或更高版本,则可以使用TRY_CONVERT
并设置捕获,例如:
declare @myfloat float;
SELECT @myfloat = TRY_CONVERT(float, typeTable.Price)
IF @myfloat IS NULL then BEGIN
PRINT 'Cast failed from '
PRINT typeTable.Price
END
ELSE BEGIN
PRINT 'cast OK'
--continue update as normal
END
请注意,TRY_CONVERT返回null或转换后的值,因此如果您正在使用实际可能为null的数据,则应在TRY_CONVERT之前显式过滤该情况。
答案 1 :(得分:0)
错误很明显,您在该列中的信息不符合要插入的列的数据类型。
在尝试插入数据之前,您需要清理数据。显然,您在数据的价格列中有不是实际价格的东西。通常这些涉及我已处理的零件号文件中的“价格征询”或“不适用”等值。
您如何处理这取决于您的业务规则。如果可以转储没有实际价格的值,您只需要对其进行过滤。如果不是没有钱的价格,那么您需要使导入失败并将数据库发送给提供修复的人。您可能还需要跳过这些记录,但将它们发送回提供程序,以便他们可以修复将来的导入。所有这些都是只有您的组织才能回答的业务决策。一旦您了解业务决策,我们就可以帮助您了解如何实施。
作为旁注,不要为此使用合并,您只是在进行更新,因此只需使用更新语句。加上合并有缺陷,我通常不推荐它用于生产数据。 - http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
特别困扰我的一件事是,您将更新所有匹配的部分,而不仅仅是更改价格的部分。这比服务器需要做的工作要多得多。没有where子句的更新通常是一个糟糕的选择。从不计划更新不需要更新的标记。你有一个大文件尤其如此。为什么只更改了3个记录时更新了一百万条记录?但即使使用小文件,也养成正确执行此操作的习惯,这样当您更新大型数据集时,这种技术对您来说很自然。