2017-11-28 11 views
0

Ich habe versucht, Datensätze mit der Merge-Anweisung in großen Mengen einzufügen/zu aktualisieren. Aber ich bekomme folgenden Fehler. Ich habe online gesucht, ich konnte keine Lösung finden. Kann mir jemand sagen, wo ich falsch liege?Fehler beim Konvertieren des Datentyps varchar in numerisch beim Einfügen/Aktualisieren.

Error converting data type varchar to numeric while inserting'

Tabellenstruktur

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, 
) 

Benutzerdefinierte Tabellentyp (erstellt Typ mit nur Spalten, die/Update einfügen muss):

CREATE TYPE [Metric].[MetricGoalType3] AS TABLE 
(
    [metricGoalId] [int] NULL, 
    [lineOfBusinessConfigId] [int] NULL,  
    [metricIndicatorId] [int] NOT NULL, 
    [goalYearConfigId] [int] NOT NULL, 
    [goalPeriodConfigId] [int] NOT NULL, 
    [marketConfigId] [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 
) 

Stored Procedure/einfügen Update mit Merge:

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 

Ex ecution (SQL Server Profiler verwendet unten Anweisungen zu erhalten)

declare @p3 Metric.MetricGoalType3 
insert into @p3 values(820,819,4,602,570,694,39.000,43.000,655,660,1585,NULL) 
insert into @p3 values(NULL,819,4,602,570,1853,NULL,NULL,655,660,NULL,NULL) 

exec Metric.prMaintainMetricGoalBulkLoad @currUserId=1618,@currProfileConfigId=301,@[email protected] 
+0

Verwenden Sie 'try_convert' oder' try_cast' anstelle von 'convert' oder' cast' –

Antwort

1

diese 2 Zeilen enthalten Fehler:

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, 

Sowohl Target und actual sind dezimal (20,3), so wie können Sie verwenden '' die string mit decimal s ist?

Es sollte

sein
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, 

selbst es keinen Sinn hat, aber zumindest gibt vill sein keine Konvertierung varchar-numeric.

Hier ist, wie Sie Ihre Fehler zu reproduzieren (I Variablen anstelle von Tabellen verwenden werden):

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 

Wenn Sie versuchen, Ihre Dezimal zu konfrontieren mit '' erhalten Sie den Fehler, da '' kann einfach nicht zu decimal umgewandelt werden .

+0

Du bist großartig. Ich habe herausgefunden, wo ich Fehler erhalte, aber ich habe keinen Weg gefunden, es zu reparieren, und es ist jetzt. Danke dir – crony

0

Es gibt Daten, die nicht korrekt konvertiert werden, genau das, was oder wo ich nicht sagen kann, aber da Sie zeigen Sie SQL Server 2012 verwenden Sie dann TRY_CONVERT verwenden oder TRY_CAST anstelle von convert oder cast.

Diese beiden neueren Funktionen verursachen keinen Fehler, wenn die Daten nicht konvertiert werden können. Stattdessen geben sie einfach NULL zurück. Während dies möglicherweise schlechte Daten nicht lösen kann, hilft es. Zum Beispiel können Sie diese in einer Where-Klausel verwenden, z.

+0

Ich habe es versucht. Aber ich bekomme den gleichen Fehler – crony

+0

"Ich habe versucht" ... * was? * Haben Sie versucht, das Problem (s) mit try_cast in einer Where-Klausel zu isolieren? Ich hoffe, du erkennst, dass alles, was ich tun kann, dich mit Werkzeugen versorgt, ich fürchte, du musst die harten Werften mit den Daten erledigen. –

0

Es sieht so aus, als ob der Einfügeteil der Anweisung nicht mit Ihrer Tabellendefinition übereinstimmt. Das dritte Feld in Ihrer Einfügeliste ist lineOfBusinessConfigId, das versucht, in das dritte Feld der Tabelle eine varchar-Spalte metricGoalName einzufügen.

Verwandte Themen