Toon posts:

[ORACLE9i2]"insert into select where" statement

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil deze statement op mijn database uitvoeren geeft alleen de volgende
foutmelding.
De foutmelding zegt dat hij geen null waardes in een kolom kan invullen.
Maar vreemde is dat ik deze kolom niet aangeef om iets in te vullen.
Hier komt de statement.

INSERT INTO world04 (countryname_id)
SELECT world04.countryname_id FROM countrycode, world04
WHERE world.iso_2digit = countrycode.iso_code2;

Hier komt de foutmelding.

insert into world04(countryname_id)
*
FOUT in regel 1:
.ORA-1400: cannot insert NULL into ("CATALOG_ADMIN"."WORLD04".OBJECTID_1")


Ik heb al op google gezocht en probeerd om het via andere statements voor elkaar te krijgen ik denk dat deze alleen bijna juist is en dat ik hier iets over het hoofd zie.

ORACLE SQL introductie boek zegt ook niets.

Ik gebruik oracle9i2 en loopt onder windows2000.
gebruik SQLplus om de statement uit te voeren.

  • j_du_pee
  • Registratie: Maart 2000
  • Laatst online: 23-09-2024

j_du_pee

du pain, du vin, du pee

Verwijderd schreef op 05 juli 2004 @ 10:48:
De foutmelding zegt dat hij geen null waardes in een kolom kan invullen.
Maar vreemde is dat ik deze kolom niet aangeef om iets in te vullen.
Dat is niet zo vreemd, als je namelijk nix invult voor die kolom komt er juist NULL in :)

Je zult dus een waarde in die kolom moeten inserten, of "allow nulls" aanzetten voor dat veld.

kaart != map && bottel != fles
Wacht op antwoord


Verwijderd

Topicstarter
Maar ik wil juist dat hij deze kolom met rust laat(dus niets invult).

  • j_du_pee
  • Registratie: Maart 2000
  • Laatst online: 23-09-2024

j_du_pee

du pain, du vin, du pee

Dan moet je in het ontwerp van de tabel dus invullen dat er null ingevuld mag worden...

kaart != map && bottel != fles
Wacht op antwoord


Verwijderd

Topicstarter
Dan wordt de waarde die in de colom OBJECTID_1 staat overschreven met een NULL waarde. En dit is juist wat ik niet wil.
Dus hij moet alleen de waarden in countryname_id in de tabel world04 overschrijven.

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Dan is het geen insert, maar een update.

Who is John Galt?


  • Maasluip
  • Registratie: April 2002
  • Laatst online: 27-08 11:33

Maasluip

Kabbelend watertje

Als je meer dan 1 veld in tabel world04 hebt en die geef je niet aan bij je insert, dan worden die automatisch met NULL gevuld. En zoals justmental al aanstipt: dit is een insert. Als je een insert doet dan worden er geen bestaande regels overschreven, dat gebeurt alleen bij een update.

Je zult dus iets moeten doen als
INSERT INTO world04 (countryname_id, objectid_1)
SELECT world04.countryname_id, "xx" FROM countrycode, world04
WHERE world.iso_2digit = countrycode.iso_code2;

Signatures zijn voor boomers.


Verwijderd

Topicstarter
Ok,

Er moeten alleen bij mij in countryname_id kolom een paar records overschreven worden. (ligt aan where statement.)
Dus ik denk dat ik een update statement moet gebruiken.
Ben nog ff aan googlen hoe de statemant er dan uitziet.

  • Maasluip
  • Registratie: April 2002
  • Laatst online: 27-08 11:33

Maasluip

Kabbelend watertje

Het moet dan iets worden als
UPDATE world04
SET world04.countryname_id = (SELECT <iets>
                              FROM <tabellen>
                              WHERE <voor je select>)
WHERE <regels van countryname_id die je wil updaten>

Signatures zijn voor boomers.


Verwijderd

Topicstarter
Ik snap nu dat het update statement moet zijn.
Deze kan alleen 1 row per keer updaten.
Ik heb deze statement gemaakt :

UPDATE catalogh_admin.world04
SET countryname_id = ( SELECT countryname_id
FROM catalog_admin.countrycode
WHERE countrycode.iso_code_2 = world04.iso_2digit)
WHERE EXISTS
(SELECT countrycode.countryname_id
FROM catalog_admin.countrycode, catalog_admin.world04
WHERE countrycode_code_2 = world04.iso_2digit);

Maar geeft nu ook een foutmelding dat hij te veel rows krijgt.
Ik heb ook een group by al geprobeerd maar dit hielp ook niet :
Hier de preciese foutmelding :

FOUT in regel 2:
.ORA-01427: single-row subquery returns more than one row.

Deels snap ik ook wel dat hij meer rows terug krijgt omdat hij bij
elke gelijke iso code de mijn countryname_id terug krijgt.
Dit zullen rond de 250 zijn.
Maar ik wil dat hij als de iso codes gelijk zijn de countryname_id van de ene countrycode tabel naar de world04 tabel geschreven wordt en dit in dezelfde record waar hij de gelijke iso code gevonden heeft.

  • Maasluip
  • Registratie: April 2002
  • Laatst online: 27-08 11:33

Maasluip

Kabbelend watertje

Wat je dus wil is dat de tabel world04 geupdate wordt zodat
de countryname_id klopt met de iso_code_2 zoals die in de tabel
countrycode staat.

Dan moet je er om te beginnen vanuit gaan dat de iso_code_2 maar
een keer in de countrycode tabel staat (anders heb je sowieso een
probleem) en dan zou ik de update zo maken:
UPDATE world04
SET countryname_id = (SELECT countryname_id
                      FROM countrycode
                      WHERE countrycode.iso_code_2 = world04.iso_2digit
                     )
;

Eventueel kun je nog zeggen dat je alleen die records in world04 wil updaten waar niets (of NULL) in staat, dan zet je tussen de ) en de ; nog een WHERE countryname_id is null countryname_id = ''.

Signatures zijn voor boomers.


Verwijderd

Topicstarter
Als ik de statement invul die jij doorgeeft krijg ik dezelfde foutmelding.
Dit komt doordat jou(mijn) where statement meedere records terug geeft.
Ik ben nu aan het zoeken hoe ik dit kan voorkomen.
Dus dat hij voor elke gevonden resultaat een update doet.
Alleen denk ik dat je dan naar PL/SQL moet gaan.
Hoewel ik denk dat dit erg beperkt voor SQL is.

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Als die subquery meerdere records oplevert, welke wil je dan gebruiken?
Als het er zomaar eentje is kun je rownum=1 toevoegen.

Who is John Galt?


  • Maasluip
  • Registratie: April 2002
  • Laatst online: 27-08 11:33

Maasluip

Kabbelend watertje

Verwijderd schreef op 05 juli 2004 @ 14:32:
Als ik de statement invul die jij doorgeeft krijg ik dezelfde foutmelding.
Dit komt doordat jou(mijn) where statement meedere records terug geeft.
Ik ben nu aan het zoeken hoe ik dit kan voorkomen.
Dan heb je records in countrycode waarbij je iso_code_2 gelijk is maar countryname_id verschilt.

Doe maar eens een
SELECT iso_code_2, count(*)
FROM countrycode
GROUP BY iso_code_2
HAVING count(*)>1
Dus dat hij voor elke gevonden resultaat een update doet.
Alleen denk ik dat je dan naar PL/SQL moet gaan.
Hoewel ik denk dat dit erg beperkt voor SQL is.
Mijn update maakt een update voor elk record in world04. Dat gaat fout als de select in de update meerdere regels terug geeft, want dan weet de update natuurlijk niet welk record hij moet gebruiken.
Dit komt of door dubbele data of door een slecht datamodel of door een ontbrekende WHERE clausule. Dit heeft verder niets met PL/SQL te maken.

Uiteraard kun je het met een leuke cursor in PL/SQL maken, maar dan nog blijf je hetzelfde probleem houden als hetgeen van waaruit je wil updaten niet eenduidig is. Lees: je mag voor elke countryname_id in countrycode maar 1 record hebben. Heb je er meer dan zul je een methode moeten vinden om je selectie te beperken.

Daarvoor is ook de select die ik in dit reply geef. Als je hier regels terug vindt dan is een van de drie problemen die ik noemde jou probleem.

Und da waren sie wieder, meine drei Probleme - Otto Waalkes

edit:
Quick-n-dirty justmental >:)

Signatures zijn voor boomers.


Verwijderd

Topicstarter
Geweldig.
Ik heb via jou script gecheckt of ik dubbele erin zat.
En ja er was een dubbele NULL waarde die ik overzien had.
Nu heb ik die weggehaald en het andere script werkt perfect.

Bedankt voor de hulp.
Pagina: 1