2017-03-15 3 views
0

Sur Oracle, j'ai une liste de noms tels que 'a', 'b', 'c' et je voudrais les insérer dans un tableau. La dimension de cette liste peut changer. donc ne peut pas le faire comme:comment ajouter une liste de noms dans un insert dans?

insert all 
    into TEMP (name) values ('a') 
    into TEMP (name) values ('b') 
    into BBU (name) values ('b') 
    into BBU (name) values ('c') 
select * from TEMP; 

Comment puis-je rendre l'insert plus dynamique? Merci

+0

Que voulez-vous dire par «J'ai une liste de noms »? De quelle manière "avez-vous" la liste? Est-ce dans une table (et si oui, sous quelle forme - en tant que lignes séparées, une par nom, ou juste comme une longue chaîne séparée par des virgules)? Est-ce une entrée de l'utilisateur? Est-ce dans un fichier texte en dehors de la base de données? "J'ai" n'est pas très utile. – mathguy

+0

Je voulais dire que j'ai une liste de valeur donnée par un autre utilisateur sous la forme suivante: "'a', 'b', 'c'" –

+0

Donc, votre entrée est une seule chaîne, de la forme "a", «b», «c»? Et vous devez le diviser en premier? Comment divisez-vous maintenant - manuellement? – mathguy

Répondre

1

utilisez un VARRAY ou une collection:

INSERT INTO TEMP (name) 
SELECT COLUMN_VALUE 
FROM TABLE(SYS.ODCIVARCHAR2LIST('a', 'b', 'c', 'd', 'e')); 

Ou utiliser une liste délimitée et split it (il existe plusieurs solutions pour diviser des chaînes délimitées à ce lien, mais on est):

INSERT INTO TEMP (name) 
SELECT x.item.getStringVal() 
FROM XMLTABLE(
     ('"a","b","c","d","e"') 
     COLUMNS item XMLTYPE PATH '.' 
     ) x; 
1

Utilisez plutôt PL/SQL. Et boucle à travers.

DECLARE 
CURSOR myCur IS 
SELECT name FROM myTable; 
TYPE xTab IS TABLE OF myCur%ROWTYPE; 
L_tab xTab; 
BEGIN 
OPEN myCur; 
FETCH myCur INTO L_tab; 
CLOSE myCur; 
FORALL i IN 1..L_tab.COUNT 
    INSERT INTO myTab2 (name) VALUES (L_tab(i).name); 
COMMIT; 
END; 
/

Maintenant, si vous êtes inquiet de dépasser votre tempspace (redo logs) coz la liste est des millions d'enregistrements, puis utilisez limite:

DECLARE 
myLimit NUMBER := 32000; 
myFlag BOOLEAN := FALSE; 
CURSOR myCur IS 
SELECT name FROM myTable; 
TYPE xTab IS TABLE OF myCur%ROWTYPE; 
L_tab xTab; 
BEGIN 
OPEN myCur; 
LOOP 
FETCH myCur INTO L_tab LIMIT myLimit; 
IF myCur%NOTFOUND 
THEN 
    IF L_tab.COUNT != 0 
    THEN 
     myFlag := TRUE; 
    ELSE 
     EXIT; 
    END IF; 
END IF; 
FORALL i IN 1..L_tab.COUNT 
    INSERT INTO myTab2 (name) VALUES (L_tab(i).name); 
COMMIT; 
EXIT WHEN myFlag = TRUE; 
END LOOP; 
CLOSE myCur; 
END; 
/
+0

Je ne pense pas que vous ayez assez d'informations de l'OP pour décider que PL/SQL est la meilleure réponse. PL/SQL ne doit être utilisé que lorsque SQL ne peut pas effectuer le travail. – mathguy

+1

D'accord, bien que ce ne soit qu'une suggestion, et cela fonctionnerait –

0

Si vos données sont enregistrées dans une colonne d'une table donnée , utilisez ce

insert into TEMP (name) 
select name_column from given_table; 
commit; 
+0

Non les données sont enregistrées dans une table donnée –