2017-08-15 2 views
0

Ich verwendete Microsoft SQL Server. Ich möchte beide Funktionen verwenden, um Daten in meine Tabelle zu parsen. Also verwende ich Cross Apply und Outer Apply zusammen.Verletzung der PRIMARY KEY-Einschränkung bei Verwendung von Kreuz anwenden und äußere zusammen anwenden

CROSS APPLY CA_Parse_CorpActnDtls_fn(MessageID) ent 
outer apply CA_Parse_CorpActnOptnDtls_fn(ev.MessageID) cod 

Aber wenn ich tat dies es zu folgendem erro klagen:

Verletzung der PRIMARY KEY-Einschränkung 'PK_AfterParse_CA_Events'. Kann doppelten Schlüssel in Objekt "Dbo.AfterParse_CA_Events" nicht einfügen. Der doppelte Schlüsselwert ist (105818432, 37819929). Die Anweisung wurde beendet.

Der ganze T-SQL-Code wie folgt aussieht:

insert into AfterParse_CA_Events (
      EventID 
      ,MessageID 
      ,cdtprFunction 
      ,CreationDate 
      ,MsgDefIdr 
      ,EventType 
      ,CFI 
      ,EventProcessingType 
      ,MndtryVlntryEvtTp 
      ,RecordDate 
      ,EffectiveDate 
      ,DueBillRdmDate 
      ,CUSIP 
      ,LSCI_DateOfRecord 
      ,RoundingDesc 

     ) 

    SELECT ent.EventID 
      ,ent.MessageID 
      ,ent.cdtprFunction 
      ,ent.CreationDate 
      ,ent.MsgDefIdr 
      ,ent.EventType 
      ,ent.CFI 
      ,ent.EventProcessingType 
      ,ent.MndtryVlntryEvtTp 
      ,ent.RecordDate 
      ,ent.EffectiveDate_Cmpny 
      ,ent.DueBillRdmDate 
      ,ent.CUSIP 
      ,ROXSQL.dbo.GetNthTradeDay_fn(
      case when ent.EventProcessingType = 'DISN' 
       then COALESCE (ent.ExDividendDate, ent.RecordDate) 
       ELSE COALESCE(ent.EffectiveDate_Xchg, ent.EffectiveDate_Cmpny,cod.EarliestPaymentDate_Secu,cod.PaymentDate_Secu ,cod.PaymentDate_Cash) 
      END,-1) AS LSCI_DateOfRecord 
      ,cod.RoundingDesc 


    FROM #EventsToDo ev 
    CROSS APPLY CA_Parse_CorpActnDtls_fn(MessageID) ent 
    outer apply CA_Parse_CorpActnOptnDtls_fn(ev.MessageID) cod 

Sie können sehen, dass ich die zweite Funktion CA_Parse_CorpActnOptnDtls_fn (ev.MessageID) benötigen weil ich ein LSCI_DateOfRecord Daten mit meinem Benutzer definiert komponieren will Funktion. Gibt es also eine Möglichkeit, das Duplikat zu vermeiden, wenn ich die beiden Funktionen zusammen benutze?

oder gibt es Möglichkeiten, eine temporäre Liste für die LSCI_DateOfRecord und RoundingDesc von der zweiten Funktion CA_Parse_CorpActnOptnDtls_fn (ev.MessageID) separat zu erstellen? Und dann kann ich die Tabelle aktualisieren.

Jede Hilfe wird sehr geschätzt.

+0

Können Sie sie in einer temporären Tabelle einfügen, das Duplikat entfernen und in der realen Tabelle einfügen? – DVT

+0

Es gibt mehrere Möglichkeiten, dies anzugehen. Aber sie alle hängen davon ab, was du mit einem Duplikat meinst. Ist es nur ein doppelter Schlüsselwert oder werden ganze Zeilen dupliziert? Vielleicht würde eine einfache Gruppe das Problem lösen. Vielleicht etwas anderes. –

+0

Einige Beispieldaten würden hier einen langen Weg zurücklegen, ebenso wie die Definition dieser 2 UDFs, die Sie haben. Dies würde uns helfen zu verstehen, was Sie als Duplikat definieren. Bitte zeigen Sie uns, was Sie bekommen (als eine Select-Anweisung) und was Sie erwarten würden – Eli

Antwort

0

Betrachtet man den Fehler und den SQL-Code, sind es nicht die APPLY-Operatoren, die das Problem per se verursachen. Es ist die Tatsache, dass eine oder beide Funktionen mehr als eine einzige Zeile für EvenID & MessageID zurückgibt, und das ist, was die PK-Verletzung verursacht.

Im Folgenden finden Sie eine vereinfachte Demonstration, eine String-Splitter-Funktion (DelimitedSplit8K)

IF OBJECT_ID('tempdb..#EventsToDo ', 'U') IS NOT NULL 
DROP TABLE #EventsToDo ; 
GO 

CREATE TABLE #EventsToDo (
    EventID BIGINT NOT NULL, 
    MessageID BIGINT NOT NULL, 
    MessageText VARCHAR(1000) NOT NULL 
    ); 
GO 

INSERT #EventsToDo (EventID, MessageID, MessageText) VALUES 
    (105818432, 37819929, 'Part 1,Part 2,Part 3,Part 4,Part 5'); 
GO 

----------------------------------------------------------------- 

-- create the AfterParse_CA_Events table with PRIMARY KEY (EvenID, MessageID)... 
IF OBJECT_ID('tempdb..#AfterParse_CA_Events', 'U') IS NOT NULL 
DROP TABLE #AfterParse_CA_Events; 
GO 

CREATE TABLE #AfterParse_CA_Events (
    EvenID BIGINT NOT NULL, 
    MessageID BIGINT NOT NULL, 
    MessagePart VARCHAR(1000) NULL 
    PRIMARY KEY (EvenID, MessageID) 
    ); 
GO 

--=============================================================== 

-- see what happens when we try to insert the parsed message values 
-- into AfterParse_CA_Events while it has a PK of (EvenID, MessageID)... 
INSERT #AfterParse_CA_Events (EvenID, MessageID, MessagePart) 
SELECT 
    etd.EventID, 
    etd.MessageID, 
    dsk.Item 
FROM 
    #EventsToDo etd 
    CROSS APPLY dbo.DelimitedSplit8K(etd.MessageText, ',') dsk; 
GO 

--=============================================================== 
-- execute the code below in a separate execution 
--=============================================================== 

-- now, let's modify the AfterParse_CA_Events table so that we have "MessagePartID" 
-- and make that part of the PK 
IF OBJECT_ID('tempdb..#AfterParse_CA_Events', 'U') IS NOT NULL 
DROP TABLE #AfterParse_CA_Events; 
GO 

CREATE TABLE #AfterParse_CA_Events (
    EvenID BIGINT NOT NULL, 
    MessageID BIGINT NOT NULL, 
    MessagePartID INT NOT NULL, 
    MessagePart VARCHAR(1000) NOT NULL 
    PRIMARY KEY (EvenID, MessageID, MessagePartID) 
    ); 
GO 

--=============================================================== 

-- Now let's try the insertion again... 
INSERT #AfterParse_CA_Events (EvenID, MessageID, MessagePartID, MessagePart) 
SELECT 
    etd.EventID, 
    etd.MessageID, 
    dsk.ItemNumber, 
    dsk.Item 
FROM 
    #EventsToDo etd 
    CROSS APPLY dbo.DelimitedSplit8K(etd.MessageText, ',') dsk; 
GO 

--=============================================================== 

-- check the inserted values... 
SELECT 
    * 
FROM 
    #AfterParse_CA_Events apce; 

HTH, Jason

Verwandte Themen