9
votes

Comment fusionner deux tables sans nommer toutes les colonnes?

Donc, disons que j'ai ces deux tables avec les mêmes colonnes. Utilisez votre imagination pour les rendre plus grandes:

CREATE TABLE USER_COUNTERPARTY
( COUNTER_ID             INTEGER       NOT NULL PRIMARY KEY,
  COUNTER_NAME           VARCHAR(38),
  COUNTER_CREDIT         INTEGER,
  COUNTER_SVRN_RISK      INTEGER,
  COUNTER_INVOICE_TYPE   VARCHAR(10) );

INSERT ALL
INTO USER_COUNTERPARTY VALUES (1, ‘Nat Bank of Transnistria’, 7, 93, ‘Automatic’)
INTO USER_COUNTERPARTY VALUES (2, ‘Acme Ltd.’, 25, 12, ‘Manual’)
INTO USER_COUNTERPARTY VALUES (3, ‘CowBInd LLP.’, 49, 12, ‘Manual’)
SELECT * FROM DUAL;

CREATE TABLE TEMP AS SELECT * FROM USER_COUNTERPARTY;
DELETE FROM TEMP;

INSERT ALL
INTO TEMP VALUES (2, ‘Conoco Ltd.’, 25, 12, ‘Automatic’)
INTO TEMP VALUES (4, ‘Disenthralled Nimrod Corp.’, 63, 12, ‘Manual’)
SELECT * FROM DUAL;


3 commentaires

Vous pouvez interroger le dictionnaire de données (E.G. user_tab_columns ) pour générer la liste des noms de colonne.


Vrai, tu peux. Mais qu'est-ce que alors? Je devrais peut-être les mettre dans une collection, la boucle et utiliser un insert dynamique. Pour mettre à jour toutes les colonnes, je pense que supprimer et insérer serait mieux. Mais je garderai le dictionnaire de données à l'esprit.


"Mais qu'est-ce que ça?" Comme je l'ai dit: génère la liste des noms de colonnes . par exemple. Sélectionnez ',' || Nom de colonne à partir d'user_tab_columns où table_name = 'MyTable' Commander par colonne_id; - Ensuite, vous copiez-la-coller et coller les résultats dans votre déclaration de fusion. Bien sûr, ce n'est pas joli et doit être ré-terminé si le schéma change, mais cela fonctionne. Certainement je ne parle pas de génération de code d'exécution :)


5 Réponses :


1
votes

Vous pouvez essayer d'utiliser une instruction Union enveloppée comme ceci:

SELECT (*) FROM
(SELECT * FROM Table1 WHERE ID NOT IN (SELECT ID FROM Table2)
 UNION ALL
 SELECT * FROM Table2)
ORDER BY 1


0 commentaires

0
votes

Si vous avez des valeurs par défaut pour les colonnes (et que vous souhaitez utiliser ces valeurs par défaut), vous pouvez omettre ceux de votre instruction insertion, mais sinon, vous devez spécifier chaque colonne que vous souhaitez insérer ou mettre à jour des valeurs.

Il n'y a pas de sténographie comme * pour sélectionnez .


0 commentaires

4
votes

Je crois que la seule option que vous devez éviter d'utiliser les noms de colonne est deux instructions distinctes: xxx


5 commentaires

Ouais, je suppose que c'est la façon de le faire.


Mais comment vous pouvez utiliser 'Sélectionnez NULL' au lieu d'un «SELECT *»? Est-ce pour l'efficacité? Devrais-je aussi faire cela?


Le SELECT dans la sous-requête à un existe est juste là pour indiquer si une ligne est renvoyée ou non, ce n'est pas ce que les colonnes sont renvoyées. Certaines personnes utiliseront SELECT 1 , d'autres SELECT * , il n'y a pas de différence réelle.


@Johndoyle Je pense que votre syntaxe est fausse pour les alias de table. Pour moi, la première requête nécessaire a été modifiée en 'Supprimer UC de User_CounterParty UC' selon Stackoverflow.com/questions/11005209/... et le second nécessaire l'alias supprimé sur la première ligne qui l'a fait" insérer dans user_counterparty '.


Une grande différence, qui doit être envisagée, c'est le fait que, avec la déclaration de suppression éventuellement existante sur Supprimer les contraintes de cascade, les tables dépendantes peuvent "perdre" des enregistrements de données. Cela ne se produit pas avec la fusion.



1
votes

Je suis tombé sur le problème décrit et la façon dont je me suis attaquée, c'est très faible technologie, mais je pensais partager au cas où cela a provoqué d'autres idées pour les personnes.

J'ai pris les noms de colonne (je les extraits de la table DDL dans le développeur SQL, mais utilisez également la méthode dans la table Tab_Columns) et les inséré dans une feuille de calcul Excel. J'ai ensuite supprimé les instructions Varchark etc. (en utilisant le texte sur la fonction Excel de colonnes, puis supprimez simplement la colonne (s) que les instructions de Varchar, etc. sont terminées dans) de sorte que cela vient de laisser les noms de champs. J'ai ensuite inséré une formule dans la prochaine colonne Excel, = "Dest." & A2 & "= SRC." & A2 & "," et rempli pour tous les 110 champs, puis dans une nouvelle colonne Excel, utilisée = A2 & "," et dans Une nouvelle colonne, = "SRC." & A2 & ",", se remplissant à nouveau pour tous les champs. Ensuite, dans une feuille SQL, j'entre: xxx

J'ai également une version pour la fusion de tables avec des noms de colonne différents, mais qui implique une étape supplémentaire de mapper les champs de l'Excel Feuille.

Je trouve que je dois utiliser des déclarations de fusion pour ce que je fais - je trouve fusionner dans un immense économiseur de temps comparé à la mise à jour où existe-t-il.


0 commentaires

0
votes

Je suis tombé sur le même problème et j'ai écrit une procédure qui obtient la liste de toutes les colonnes de table et crée une requête SQL dynamique pour effectuer une mise à jour sans nommer toutes les colonnes.

-- Insert not matching records
INSERT INTO USER_COUNTERPARTY
            SELECT *
            FROM TEMP WHERE COUNTER_ID NOT IN (
        SELECT USER_COUNTERPARTY.COUNTER_ID 
        FROM USER_COUNTERPARTY 
        JOIN TEMP ON TEMP.COUNTER_ID = USER_COUNTERPARTY.COUNTER_ID);
-- Update matching records
update_from_table('TEMP', 'USER_COUNTERPARTY', 'COUNTER_ID');


0 commentaires