Sql 插入/更新时将数据类型varchar转换为数字时出错
我试图使用merge语句批量插入/更新记录。但我得到以下错误。我在网上搜索过,但找不到修复的方法。有人能告诉我哪里做错了吗 插入时将数据类型varchar转换为数值时出错' 表结构Sql 插入/更新时将数据类型varchar转换为数字时出错,sql,sql-server,database,sql-server-2012,Sql,Sql Server,Database,Sql Server 2012,我试图使用merge语句批量插入/更新记录。但我得到以下错误。我在网上搜索过,但找不到修复的方法。有人能告诉我哪里做错了吗 插入时将数据类型varchar转换为数值时出错' 表结构 CREATE TABLE [Metric].[MetricGoal] ( [metricGoalId] [int] IDENTITY(1,1) NOT NULL, [profileConfigId] [int] NOT NULL, [metricGoalName] [varchar](20
CREATE TABLE [Metric].[MetricGoal]
(
[metricGoalId] [int] IDENTITY(1,1) NOT NULL,
[profileConfigId] [int] NOT NULL,
[metricGoalName] [varchar](200) NULL,
[metricIndicatorId] [int] NOT NULL,
[marketConfigId] [int] NOT NULL,
[regionConfigId] [int] NOT NULL,
[goalYearConfigId] [int] NOT NULL,
[goalPeriodConfigId] [int] NOT NULL,
[targetValue] [decimal](20, 3) NULL,
[actualValue] [decimal](20, 3) NULL,
[metricGoalStatusConfigId] [int] NOT NULL,
[metricGoalStatusReasonConfigId] [int] NOT NULL,
[ownerId] [int] NULL,
[workerId] [int] NULL,
[createdOn] [datetime] NOT NULL,
[createdBy] [int] NOT NULL,
[updatedOn] [datetime] NOT NULL,
[updatedBy] [int] NOT NULL,
[lineOfBusinessConfigId] [int] NULL,
[productConfigId] [int] NULL,
[serviceAreaConfigId] [int] NULL,
)
用户定义的表类型(创建的类型仅包含需要插入/更新的列):
要使用“合并”插入/更新的存储过程:
CREATE PROCEDURE [Metric].[prMaintainMetricGoalBulkLoad]
@currUserId INT = NULL,
@currProfileConfigId INT = NULL,
@tblMetricGoal [Metric].[MetricGoalType3] READONLY
AS
DECLARE @now DATETIME = GETDATE()
BEGIN
SET NOCOUNT ON;
MERGE INTO [Metric].[MetricGoal] T
USING @tblMetricGoal S ON (T.metricGoalId = S.metricGoalId)
WHEN MATCHED
THEN UPDATE
SET T.targetValue = CASE WHEN S.targetValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,'')),T.targetValue) END,
T.actualValue = CASE WHEN S.actualValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,'')),T.actualValue) END,
T.metricGoalStatusConfigId = CASE WHEN S.metricGoalStatusConfigId = -1 THEN NULL ELSE ISNULL(S.metricGoalStatusConfigId,T.metricGoalStatusConfigId) END,
T.metricGoalStatusReasonConfigId = CASE WHEN S.metricGoalStatusReasonConfigId = -1 THEN NULL ELSE ISNULL(S.metricGoalStatusReasonConfigId,T.metricGoalStatusReasonConfigId) END,
T.ownerId = CASE WHEN S.ownerId = -1 THEN NULL ELSE ISNULL(S.ownerId,T.ownerId) END,
T.workerId = CASE WHEN S.workerId = -1 THEN NULL ELSE ISNULL(S.workerId,T.workerId) END,
T.updatedOn = @now,
T.updatedBy = @currUserId
WHEN NOT MATCHED BY TARGET
THEN INSERT (profileConfigId,
--metricGoalName,
metricIndicatorId, lineOfBusinessConfigId, marketConfigId,
--productConfigId,
--serviceAreaConfigId,
--regionConfigId,
goalYearConfigId, goalPeriodConfigId, targetValue, actualValue,
metricGoalStatusConfigId, metricGoalStatusReasonConfigId,
ownerId, workerId, createdOn, createdBy,
updatedOn, updatedBy)
VALUES (@currProfileConfigId,
--S.metricGoalName,
S.metricIndicatorId, S.lineOfBusinessConfigId, S.marketConfigId,
--NULLIF(S.productConfigId,-1),
--NULLIF(S.serviceAreaConfigId,-1),
--S.regionConfigId,
S.goalYearConfigId, S.goalPeriodConfigId,
CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,'')),
CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,'')),
S.metricGoalStatusConfigId, S.metricGoalStatusReasonConfigId,
NULLIF(S.ownerId, -1),
NULLIF(S.workerId, -1),
@now, @currUserId, @now, @currUserId);
END
执行(使用SQL Server探查器获取以下语句)
有些数据无法正确转换,确切地说是什么或在什么地方转换,但由于您表示正在使用SQL Server 2012,请使用或而不是
convert
或cast
如果无法转换数据,这两个较新的函数不会导致故障,它们只返回NULL。虽然这可能无法解决坏数据,但确实有帮助。例如,您可以在where子句中使用这些
select *
from to_be_imported
where try_convert(date,stringcolumn) IS NULL
语句的insert部分似乎与表定义不一致。插入列表中的第三个字段是LineOfBusiness ConfigId,它试图插入表的第三个字段,即varchar列metricGoalName 这两行包含错误:
T.targetValue = CASE WHEN S.targetValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,'')),T.targetValue) END,
T.actualValue = CASE WHEN S.actualValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,'')),T.actualValue) END,
targetValue和actualValue都是十进制的(20,3),那么如何将'
即字符串与十进制一起使用呢
应该是
T.targetValue = CASE WHEN S.targetValue is null THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,null)),T.targetValue) END,
T.actualValue = CASE WHEN S.actualValue is null THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,null)),T.actualValue) END,
即使它没有意义,但至少不会从varchar
转换为numeric
下面是如何重现错误(我将使用变量而不是表格):
当你试图用'
来对抗十进制时,你会得到错误,因为'
无法转换成十进制
使用try\u convert
或try\u cast
而不是convert
或cast
“我已经尝试过”。。。什么?您是否尝试在where子句中使用try_cast隔离问题?我希望你能意识到我所能做的就是给你提供工具,恐怕你得用这些数据做艰苦的工作你太棒了。我确实找到了错误的地方,但没有找到解决方法,现在就是。多亏了你
T.targetValue = CASE WHEN S.targetValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,'')),T.targetValue) END,
T.actualValue = CASE WHEN S.actualValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,'')),T.actualValue) END,
T.targetValue = CASE WHEN S.targetValue is null THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.targetValue,null)),T.targetValue) END,
T.actualValue = CASE WHEN S.actualValue is null THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(S.actualValue,null)),T.actualValue) END,
declare @StargetValue DECIMAL(20,3) = 10, @TtargetValue DECIMAL(20,3) = 20;
set @ttargetValue = CASE WHEN @StargetValue = '' THEN NULL ELSE ISNULL(CONVERT(DECIMAL(20,3),NULLIF(@StargetValue,'')),@TtargetValue) END