2017-07-12 5 views
0

Ich arbeite an einer gespeicherten Prozedur, die Zeilen in einer Remote-Tabelle einfügen oder aktualisieren soll. Ich habe versucht, MERGE zu verwenden, aber es ist nicht möglich, MERGE zu verwenden, wenn die Zieltabelle eine Fernbedienung ist.Parameterlose gespeicherte Prozedur zum Aktualisieren einfügen

Kann mir jemand zeigen, wie kann ich auch das Update innerhalb der Sproc tun? Muss ich zuerst die Datensätze in eine temporäre Tabelle einlesen und dann die Werte vergleichen? Der Spaltenwert, den ich aktualisieren möchte, ist FlagValue.

UPDATE

konnte ich einen Verbindungsserver auf dem anderen Server erstellen und das Ziel und Quelle gekippt.

Ich stelle eine gespeicherte Prozedur zusammen, die MERGE verwendet, ich frage mich, ob jemand mir helfen könnte, den Code zu überprüfen und mich wissen zu lassen, ob es in Ordnung ist. Der Code muss im Grunde die FlagValue-Spalte aktualisieren, wenn der SKU bereits in der Zieltabelle enthalten ist, der FlagValue-Wert jedoch anders ist und Datensätze einfügen, die ebenfalls auf SELECT innerhalb von USING() als SOURCE beschränkt sind Datensätze aus dem Tabellenprodukt.

AKTUALISIERT T-SQL:

ALTER PROCEDURE [dbo].[mn_RecordInfo_Upsert] 
AS 
BEGIN 

    --Synchronize the target table with refreshed data from source table 
    MERGE [dbo].[RecordInfo] AS [t] 
    USING 
     (SELECT TOP 100 PERCENT 
      [p].[ProductID] 
      , [p].[Flag] 
      FROM 
      [server].[db].[dbo].[Product] [p] -- Remote linked server table 
      WHERE 
      (
       [Category] = 2 
       OR [Description] = 'This type of product') 
      AND LEN([ProductID]) = 10 
      AND [ProductID] LIKE 'P0%' 
      ORDER BY 
      [Date] DESC 
     ) AS [s] 
    ON ([t].[PID] = [s].[ProductID]) 

    --When records are matched, update the records if there is any change 
    WHEN MATCHED AND [t].[Flag] <> [s].[Flag] 
     AND [t].[PID] = [s].[ProductID] THEN 
     UPDATE SET 
       [t].[Flag] = [s].[Flag]       

    --When no records are matched, insert the incoming records from source table to target table 
    WHEN NOT MATCHED BY TARGET THEN 
     INSERT 
       (
       [PID] 
       , [Flag]) 
     VALUES (
       [s].[ProductID] 
       , [s].[Flag])  

    --SELECT @@ROWCOUNT; 
    OUTPUT 
     $action AS [DMLAction] 
     , [inserted].* 
     , [deleted].*; 
END; 

Vielen Dank für Ihre Empfehlungen.

+3

Eine Lösung besteht darin, die gespeicherte Prozedur auf dem Remote-Server zu erstellen. Dann können Sie 'MERGE' verwenden. – Eric

+1

Was UPDATE? Zeigen Sie uns das Update, das Sie ausführen möchten. – RBarryYoung

+0

Ich habe es gerade hinzugefügt. Mein Fehler. –

Antwort

1

Wenn ich Ihre Frage zu verstehen, nur was Sie geschrieben haben tut, was Sie denken, dass es tut? Ich glaube es tut es. Ihr Update sieht gut aus, obwohl das erneute Verbinden target.sku = source.sku redundant ist. Alle verschiedenen Anweisungen in einer einzelnen Zusammenführungsanweisung (z. B. when matched, when not matched by source,) verwenden die oben angegebenen Verknüpfungskriterien, sodass Sie sie nicht erneut angeben müssen. Eine andere Sache zu prüfen ist, ob FlagValue Null sein kann. Wenn dies der Fall ist, wird überprüft, dass target.FlagValue != source.FlagValue den Wert false seit zurückgibt.

Wie für Ihren Einsatz sind Sie richtig. Es verwendet nur die Ergebnisse der Unterabfrage, die Sie definiert und Alias ​​als source (Randnotiz, obwohl MSDN gerne Alias ​​sie source und target, ich mag s und t wie sie sind nicht reservierte Schlüsselwörter und vermeidet Verwirrung, wenn Sie beenden Ende mit source und target als tatsächlichen Keywords, wenn Sie beispielsweise eingeben, when not matched by target. Der Punkt ist, können Sie sie Alias, was Sie wollen, Sie sind nicht auf diese beiden Schlüsselwörter beschränkt).

Wenn Sie wissen möchten, was während der Ausführung vor sich geht, können Sie zwei Dinge tun. Die erste besteht darin, am Ende eine OUTPUT Klausel zu verwenden; etwas so einfach wie

... 
(
    [SOURCE].[SKU], 
    [SOURCE].[FlagValue] 
) 
output $action as DMLAction, inserted.*, deleted.* 

Wenn Sie finden MERGE klobig, mit zu arbeiten, würde der zweite Ansatz zu schreiben diese als zwei getrennte Erklärungen zu prüfen sein, anstelle ein MERGE; ein insert und ein update. In den meisten Fällen, ein MERGE tut das sowieso, so dass Sie nicht auf Leistung verlieren, und es ist in der Regel einfacher, eine insert oder update Aussage als eine merge meiner Erfahrung nach zu picken.

Auch ich muss ein verbindliches Wort der Vorsicht geben, wenn Sie über einen Verbindungsserver verbinden. Manchmal wird es gut funktionieren, aber manchmal wird es seine eigene Sache ganz machen.Wenn die entfernte Tabelle groß ist, könnte es passieren, dass Sie die gesamte Tabelle scannen und sie über den Verbindungsserver leiten, selbst wenn Sie nicht erwarten würden, dass die Tabelle so nahe an einen Plan kommt, dass die lokale Tabelle schlecht ist.

+1

Hallo Xedni, ich aktualisiere meinen Post mit der letzten Version meines Codes. Ich denke, es tut, was ich tun muss. Vielen Dank für Ihre Erklärung. –

Verwandte Themen