2013-02-09 4 views
2

Vous trouverez ci-dessous la table dans laquelle ID column is Primary Key. Et les deux autres colonnes sont des chaînes. J'utilise une nouvelle base de données nommée XpressMP.Procédure stockée pour la fonctionnalité UPSERT

Column Name     
------- 
ID    PrimaryKey     
SEARCHES  String 
ACCOUNT  String 

Je suis en train de réaliser la fonctionnalité de UPSERT ici-

If ID doesn't exists here then insert a new record. 
And ID exists then update the record. 

Je sais que si je travaille avec Oracle, je peux alors utiliser MERGE commande SQL mais MERGE est pas pris en charge dans cette base de données et il est pas d'autre commande pour ça dès maintenant. Mais je crois que je peux faire la même chose avec Stored Procedure.

Quelqu'un peut-il fournir des suggestions comment puis-je faire la même chose avec la procédure stockée? Comme procédure stockée travaillera là.

Mis à jour: -

public final static String INSERT = "BEGIN" 
+" INSERT INTO TABLE (ID, SEARCHES, ACCOUNT) VALUES (?, ?, ?)" 
+" EXCEPTION" 
+" WHEN DUP_VAL_ON_INDEX THEN" 
+" UPDATE TABLE" 
+" SET SEARCHES = ?, ACCOUNT = ?" 
+" WHERE ID = ?" 
+" END"; 

Chaque fois que je tente d'exécuter la procédure stockée ci-dessus comme celui-ci

preparedStatement = dbConnection.prepareStatement(INSERT); 

preparedStatement.setString(1, String.valueOf(userId)); 
preparedStatement.setString(2, Constants.getaAccount(userId)); 
preparedStatement.setString(3, Constants.getaAdvertising(userId)); 
preparedStatement.executeUpdate(); 

Je me exception? Est-ce la bonne façon de l'exécuter?

Répondre

0

Vous pouvez le manipuler à l'aide l'exception DUP_VAL_ON_INDEX.
Vous pouvez ajouter le code ci-dessous dans votre procédure, ce qui devrait répondre à vos besoins.

CREATE OR REPLACE PROCEDURE TABLE_UPSERT (v_id IN NUMBER, 
              v_searches IN VARCHAR2(20), 
              v_account IN VARCHAR2(20)) AS 
BEGIN 
    INSERT INTO table (id, searches, account) VALUES (v_id, v_searches, v_account) ; 
EXCEPTION 
    WHEN DUP_VAL_ON_INDEX THEN 
    UPDATE TABLE 
    SET searches = v_searches, account = v_account 
    WHERE id = v_id; 
END; 
/

Vous pouvez en savoir plus sur DUP_VAL_ON_INDEX Exception here et here. Une autre option consisterait à insérer ou à mettre à jour les données après vérification du compte.

DECLARE 
    l_count number; 
BEGIN 
    SELECT count(*) 
    INTO l_count 
    FROM table 
    WHERE id = (value); 

    IF l_count = 0 THEN 
    INSERT into table VALUES ....; 
    ELSE 
    UPDATE table SET searches = .., account = ..; 
    END IF; 
END; 
+0

Merci Orangecrush pour l'aide. Jetez un oeil dans 'DUP_VAL_ON_INDEX'. Comme je vais utiliser Java pour appeler cette procédure stockée.J'ai donc modifié votre SP pour que ça fonctionne. 'BEGIN INSERT DANS TABLE (ID, RECHERCHES, COMPTE) VALEURS (?,?,?); EXCEPTION QUAND DUP_VAL_ON_INDEX PUIS MISE À JOUR TABLEAU SET SEARCHES =?, ACCOUNT =? O WH ID =?; FIN; '. Cela devrait fonctionner correctement? Comme je remplis ... avec? marque. –

+0

@FarhanJamal Oui, devrait fonctionner si vous manipulez la variable correctement dans Java en appelant cette procédure. Essaie. Ont également donné édité et provied un code plus simple à comprendre, si vous voulez essayer celui-là. Mais je suggère d'utiliser 'DUP_VAL_ON_INDEX'. – Orangecrush

+0

@FarhanJamal Je suppose que vous appellerez ce SP de java en utilisant 'SP (?,?,?)'. Vous ne pouvez pas utiliser '?' Pour une valeur de variable dans une procédure PL/SQL. – Orangecrush

1

Eh bien, je pense que vous devez le faire de manière traditionnelle.

SI ROW INEXISTANTE INSERT AUTRE MISE À JOUR

+0

Ouais je le sais déjà :). Mais quelle est cette manière traditionnelle? Procédures stockées, n'est-ce pas? –

+0

Son votre décision de conception .i Recommandé Procédure stockée. – Tabish

+0

Ouais c'est ce que je pense aussi. Pouvez-vous me fournir un exemple lié à la procédure stockée qui fonctionnera dans mon cas? –

1

Je suis d'accord avec @tabish ici. vous devrez le faire de la manière traditionnelle. comme vous l'avez suggéré, je pense que vous causez plus de dégâts - vous effectuez une insertion pour chaque ligne de la table source (soit vers la table cible, soit vers la table ERR) puis effectuez une mise à jour supplémentaire. Dans le pire des cas, lorsque vous devez mettre à jour toutes les lignes, vous effectuerez deux fois plus d'opérations dml. ce n'est pas une bonne idée dans mon livre. Bonne chance.