2009-02-28 5 views
1

Ich erstelle eine Prozedur zum Aktualisieren/Einfügen einer Tabelle mit Merge-Anweisung (Upsert). Jetzt habe ich ein Problem: mit Prozedur-Parameter muss ich dies Upsert tun.So verwenden Sie Prozedurparameter in Merge-Anweisung

Prozedur xyz (a in Tabelle.a% Typ, b in Tabelle.b% Typ, ....) ist einige lokale Variablen; beginnen verschmelzen zu target_table mit SOURCE_TABLE - anstelle der Quelltabelle, habe ich hier Prozedurparameter auf (Bedingung in der Tabelle auf Primärschlüssel) verwenden wenn angepasst dann Aktualisierung der Tabelle wenn nicht dann abgestimmt die Tabelle einfügen; Ende xyz; so, wie Prozessparameter statt Quellentabelle in Merge-Anweisung zu verwenden? oder schlagen Sie mir eine Abfrage vor, um die Prozedurparameter abzurufen und sie als Quelltabellenwerte zu verwenden.

hilf mir bitte. Vielen Dank im Voraus.

+0

Hallo Raskart, Kasse neue Version, sollte dies in Ordnung sein. –

Antwort

0

Maby so etwas wie

DECLARE V_EXISTS NUMBER; 
BEGIN SELECT COUNT(*) INTO V_EXISTS FROM TARGET_TABLE WHERE PK_ID = :ID; 

    IF V_EXISTS > 0 THEN 
     -- UPDATE 
    ELSE 
     -- INSERT 
    END IF; 
END; 

Auch Sie können versuchen tempotary Tabelle zu verwenden (wählen Sie aus DUAL)

CREATE TABLE TEST (N NUMBER(2), NAME VARCHAR2(20), ADRESS VARCHAR2(100)); 
INSERT INTO TEST VALUES(1, 'Name1', 'Adress1'); 
INSERT INTO TEST VALUES(2, 'Name2', 'Adress2'); 
INSERT INTO TEST VALUES(3, 'Name3', 'Adress3'); 
SELECT * FROM TEST; 
-- test update 
MERGE INTO TEST trg 
USING (SELECT 1 AS N, 'NameUpdated' AS NAME, 
    'AdressUpdated' AS ADRESS FROM Dual) src     
ON (src.N = trg.N) 
WHEN MATCHED THEN 
    UPDATE 
    SET trg.NAME = src.NAME, 
     trg.ADRESS = src.ADRESS 
WHEN NOT MATCHED THEN 
    INSERT VALUES (src.N, src.NAME, src.ADRESS); 
SELECT * FROM TEST; 
-- test insert 
MERGE INTO TEST trg 
USING (SELECT 34 AS N, 'NameInserted' AS NAME, 
    'AdressInserted' AS ADRESS FROM Dual) src     
ON (src.N = trg.N) 
WHEN MATCHED THEN 
    UPDATE 
    SET trg.NAME = src.NAME, 
     trg.ADRESS = src.ADRESS 
WHEN NOT MATCHED THEN 
    INSERT VALUES (src.N, src.NAME, src.ADRESS); 
SELECT * FROM TEST; 
DROP TABLE TEST; 

siehe here

+0

Hallo coldice, Danke für die Antwort .. Ich bin auf der Suche nach einer Abfrage, so dass es die Prozedur Parameter direkt anstelle von source_table/view in merge stmt verwendet. Diese Abfrage sollte die Werte (z. B. Parameter) nach dem Schlüsselwort "Verwenden" in der Zusammenführungsanweisung bereitstellen. – raskart

+0

Hallo coldice, ich habe versucht, die temporäre Tabelle Methode, aber es zeigt Fehler "Ora: 00969: fehlende ON-Schlüsselwort". – raskart

+0

Hallo coldice .. Danke für die freundliche Hilfe ya ...... – raskart

0

Seine so genannten sehr schwierig aus zu sagen, Du stellst genau in Frage, was du hast, aber ich nehme an, du willst, dass der Tisch, in den du dich einmachst (oder auf), dynamisch ist. In diesem Fall, was Sie verwenden sollten, ist das DBMS_SQL Paket zum Erstellen von dynamischen SQL

0

Ich weiß, dass ich acht Jahre zu spät zur Party bin, aber ich denke, dass ich versuchte, etwas zu tun, was Sie tun , aber versuchen, Upsert basierend auf Parametern, die an eine gespeicherte Prozedur übergeben werden, die bei Erfolg eine leere Zeichenfolge und einen Fehler bei Fehler zurück an meinen VB-Code zurückgibt. Im Folgenden finden Sie meinen gesamten Code zusammen mit Kommentaren, die erklären, was ich getan habe und warum ich es getan habe. Lass es mich wissen, wenn dir das hilft oder sonst jemand. Dies ist das erste Mal, dass ich einen Beitrag beantworte.

PROCEDURE UpsertTSJobData(ActivitySeq_in IN NUMBER, 
    Owner_in In VARCHAR2, 
    NumTrailers_in IN NUMBER, 
    ReleaseFormReceived_in IN NUMBER, 
    Response_out OUT VARCHAR2) AS 

    err_num NUMBER; 
    err_msg VARCHAR2(4000); 

    BEGIN 
    --This top line essentially does a "SELECT *" from the named table 
    --and looks for a match based on the "ON" statement below 
    MERGE INTO glob1app.GFS_TS_JOBDATA_TAB tsj 
    --This select statement is used for the INSERT when no match 
    --is found and the UPDATE when a match is found. 
    --It creates a "pseudo-table" 
    USING (
     SELECT ActivitySeq_in AS ActSeq, 
     Owner_in As Owner, 
     NumTrailers_in As NumTrailers, 
     ReleaseFormReceived_in As ReleaseFormReceived 
     FROM DUAL) input 
    --This ON statement is what we're doing the match on to find 
    --matching records. This decides whether it will be an 
    --INSERT or an UPDATE 
    ON (tsj.Activity_seq = ActivitySeq_in) 
    WHEN MATCHED THEN 
     --Here we UPDATE based on the passed in input table 
     UPDATE 
     SET OWNER = input.owner, 
      NUMTRAILERS = input.NumTrailers, 
      RELEASEFORMRECEIVED = input.releaseformreceived 
    WHEN NOT MATCHED THEN 
     --Here we INSERT based on the passed in input table 
     INSERT (
     ACTIVITY_SEQ, 
     OWNER, 
     NUMTRAILERS, 
     RELEASEFORMRECEIVED 
     ) 
     VALUES (
     input.actseq, 
     input.owner, 
     input.numtrailers, 
     input.releaseformreceived 
    ); 

    Response_out := ''; 

    EXCEPTION 
     WHEN OTHERS THEN 
     err_num := SQLCODE; 
     err_msg := SUBSTR(SQLERRM, 1, 3900); 
     Response_out := TO_CHAR (err_num) || ': ' || err_msg; 
    END;