2008-09-22 5 views
0

J'ai une compréhension plutôt faible de l'une des fonctionnalités les plus avancées d'Oracle, mais cela devrait être possible.Oracle: Existe-t-il un moyen simple de dire "si null conserve la valeur actuelle" dans les instructions de fusion/mise à jour?

Dire que j'ai une table avec le schéma suivant:

MyTable 
    Id INTEGER, 
    Col1 VARCHAR2(100), 
    Col2 VARCHAR2(100) 

Je voudrais écrire un sproc avec les éléments suivants

PROCEDURE InsertOrUpdateMyTable(p_id in integer, p_col1 in varcahr2, p_col2 in varchar2) 

qui, dans le cas d'une mise à jour, si le valeur p_col1, p_col2 est nul ne remplacera pas Col1, Col2 respectivement

donc, si j'ai un dossier:

id=123, Col1='ABC', Col2='DEF' 

exec InsertOrUpdateMyTable(123, 'XYZ', '098'); --results in id=123, Col1='XYZ', Col2='098' 
exec InsertOrUpdateMyTable(123, NULL, '098'); --results in id=123, Col1='ABC', Col2='098' 
exec InsertOrUpdateMyTable(123, NULL, NULL); --results in id=123, Col1='ABC', Col2='DEF' 

Existe-t-il un moyen simple de le faire sans avoir plusieurs instructions SQL?

Je pense qu'il pourrait y avoir un moyen de le faire avec l'instruction Merge, bien que je ne le connaisse que moyennement.


EDIT: Cade Roux ci-dessous suggère d'utiliser COALESCE qui fonctionne très bien! Here are some examples of using the coalesce kewyord. Et voici la solution pour mon problème:

MERGE INTO MyTable mt 
    USING (SELECT 1 FROM DUAL) a 
    ON (mt.ID = p_id) 
    WHEN MATCHED THEN 
     UPDATE 
      SET mt.Col1 = coalesce(p_col1, mt.Col1), mt.Col2 = coalesce(p_col2, mt.Col2) 
    WHEN NOT MATCHED THEN 
     INSERT (ID, Col1, Col2) 
     VALUES (p_id, p_col1, p_col2); 
+0

Je pense que le wrapper d'instruction MERGE ne fait qu'obscurcir les choses ici. Dans une telle fusion d'une ligne, je garderais la mise à jour séparée et piégerais un "si sql% notfound puis insert" le suivant. –

+0

@Nick: vous êtes mieux lotis avec la fusion. Quelqu'un d'autre peut jouer avec vos données entre deux instructions SQL –

Répondre

1

aide et MERGE COALESCE? Try this link for an example

avec

SET a.Col1 = COALESCE(incoming.Col1, a.Col1) 
    ,a.Col2 = COALESCE(incoming.Col2, a.Col2) 
+0

Comment faire ceci ?! S'il vous plaît dites-moi. –

+0

Ah, merci, laissez-moi donner un coup de feu –

+0

Wondefully élégant –

2

Modifier l'appel ou la déclaration de mise à jour à utiliser

nvl(newValue, oldValue) 

pour la nouvelle valeur sur le terrain.

+0

Mais alors je dois sortir oldValue dans une autre instruction SQL, sauf si vous savez quelque chose que je ne sais pas –

Questions connexes