Wie wäre es, die Daten mit einer Scriptsprache deiner Wahl aufzuteilen?
Ansonsten könnten dir ev. noch RULEs weiterhelfen, aber da bin ich mir gerade nicht ganz sicher. Siehe Dokumentation "CREATE RULE".
Hallo,
ich möchte eine csv (excel) Tabelle in zwei DB-Tabelle kopieren (Contact und Company).
Die csv Datei:
Name;Vorname;Company;;
Die DB Tabelle Contact:
Contact_ID; Name; Vorname; Company_ID
Die DB Tabelle Contact:
Company_ID; Company_Name
Die Tabellen sind über Company_ID verbunden.
Ich will das die Spalten Name und Vorname aus der csv Tabelle automatsch in die Contact DB- Tabelle
und die Spalte Company automatsch in die Company DB- Tabelle
kopiert wird und die Zusammengehörigkeit(Contact.Company_ID = Company.Company_ID) gleich mit verbunden wird.
hab leider keine Idee
vielen Dank
Frank
Wie wäre es, die Daten mit einer Scriptsprache deiner Wahl aufzuteilen?
Ansonsten könnten dir ev. noch RULEs weiterhelfen, aber da bin ich mir gerade nicht ganz sicher. Siehe Dokumentation "CREATE RULE".
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
[QUOTE=ads;10495]Wie wäre es, die Daten mit einer Scriptsprache deiner Wahl aufzuteilen?
Das Problem ist, daß er in seiner Scriptsprache seiner Wahl nicht wissen kann, welche ID eine Company hat. Dazu müßte er die DB befragen, dabei notfalls die Company erst einmal einfügen. Von daher halte ich diesen Ansatz für, ähm, schlecht.
Könnten, wenn eine RULE bei COPY wirken würde. Tut sie nicht. Was geht, wäre ein TRIGGER. Ich habe da mal a bissl gespielt, dabei nutze ich eine Hilfstabelle, die den Aufbau der CSV-Datei hat:Ansonsten könnten dir ev. noch RULEs weiterhelfen, aber da bin ich mir gerade nicht ganz sicher. Siehe Dokumentation "CREATE RULE".
Btw.: ich nutze dabei auch Avoid Unique Key violation - ads' corner *g*
Der TRIGGER feuert also beim COPY. Man braucht nun also nur noch die Triggerfunktion sinnvoll zu schreiben. Das überlasse ich mal dem Fragesteller zur Übung. Er könnte auch die RULE nutzen, dazu einfach nur 2 gleich aufgebaute Hilfstabellen: in die eine erst mit COPY die Daten reintun, dann via INSERT die Daten in die zweite werfen. Auf dieser liegt dann die RULE.PHP-Code:test=# create table company (id serial primary key, name text);
NOTICE: CREATE TABLE will create implicit sequence "company_id_seq" for serial column "company.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "company_pkey" for table "company"
CREATE TABLE
test=*# create table contact (id serial primary key, name text, vorname text, company int references company);
NOTICE: CREATE TABLE will create implicit sequence "contact_id_seq" for serial column "contact.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "contact_pkey" for table "contact"
CREATE TABLE
test=*# commit;
COMMIT
test=# create table contact_import (name text, vorname text, company text);
CREATE TABLE
-- Versuch mit RULE
test=*# create rule my_import as on insert to contact_import do instead ( insert into company (name) select NEW.company where not exists (select name from company where name=NEW.company); insert into contact (name, vorname, company) select NEW.name, NEW.vorname, id from company where name=NEW.company; );
CREATE RULE
test=*# copy contact_import from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> name1 vorname1 firma1
>> name2 vorname2 firma2
>> name11 vorname11 firma1
>> \.
test=*# select * from company;
id | name
----+------
(0 rows)
test=*# select * from contact;
id | name | vorname | company
----+------+---------+---------
(0 rows)
test=*# select * from contact_import ;
name | vorname | company
--------+-----------+---------
name1 | vorname1 | firma1
name2 | vorname2 | firma2
name11 | vorname11 | firma1
(3 rows)
-- die RULE wirkt also nicht bei COPY
-- Versuch RULE mit INSERT
test=*# rollback;
ROLLBACK
test=# create table contact_import (name text, vorname text, company text);
CREATE TABLE
test=*# create rule my_import as on insert to contact_import do instead ( insert into company (name) select NEW.company where not exists (select name from company where name=NEW.company); insert into contact (name, vorname, company) select NEW.name, NEW.vorname, id from company where name=NEW.company; );
CREATE RULE
test=*# insert into contact_import values('name1','vorname1','firma1');
INSERT 0 1
test=*# insert into contact_import values('name2','vorname2','firma2');
INSERT 0 1
test=*# insert into contact_import values('name11','vorname11','firma1');
INSERT 0 1
test=*# select * from company;
id | name
----+--------
1 | firma1
2 | firma2
(2 rows)
test=*# select * from contact;
id | name | vorname | company
----+--------+-----------+---------
1 | name1 | vorname1 | 1
2 | name2 | vorname2 | 2
3 | name11 | vorname11 | 1
(3 rows)
-- schon besser, aber wenn die Daten als CSV vorliegen, ist ein COPY schöner als daraus erst INSERT zu frickeln.
-- was also tun?
-- Versuch mit TRIGGER, nicht ausformuliert, nur ein Test, ob der Trigger bei COPY feuert:
test=# create table contact_import (name text, vorname text, company text);
CREATE TABLE
test=*# create function my_copy() returns trigger as $$begin raise notice 'test';return NEW; end;$$ language plpgsql;
CREATE FUNCTION
test=*# create trigger m_tg before insert on contact_import for each row execute procedure my_copy();
CREATE TRIGGER
test=*# copy contact_import from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> a1 b1 c1
>> a2 b2 c2
>> a11 b11 c1
>> \.
NOTICE: test
CONTEXT: COPY contact_import, line 1: "a1 b1 c1"
NOTICE: test
CONTEXT: COPY contact_import, line 2: "a2 b2 c2"
NOTICE: test
CONTEXT: COPY contact_import, line 3: "a11 b11 c1"
test=*#
So, nun aber erst mal einen Kaffee...
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
ui!!
Ich hab gestern schon angefangen selber ein Skript zu entwerfen, aber das ist ja super!!
Mir fehlt zwar noch etwas Verständnis dafür, weil ich gerade erst mit dem SQL Gedöns angefangen hab, aber das werd ich dank deiner Hilfe übernehmen.
Wie komme ich dan an so eine sql Konsole ran? (ich nehm an das ist solch eine auf der du das geschrieben hast)
greez
Frank
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
habs gefunden!!!
ich nochmals,
habe die funktion geändert und bekomme eine meldung:
control reached end of trigger without return
was hab ich falsch gemacht
dankeCode:CREATE OR REPLACE FUNCTION my_copy2() RETURNS "trigger" AS 'begin insert into company (name) select NEW.company where not exists (select name from company where name=NEW.company); insert into contact (name, vorname, company) select NEW.name, NEW.vorname, id from company where name=NEW.company; end;' LANGUAGE 'plpgsql' VOLATILE; ALTER FUNCTION my_copy2() OWNER TO postgres;
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
nö,
mir zumindest nicht
Deine Funktion muss ein RETURN enthalten.
Da du eine TRIGGER Funktion definierst, musst du auch einen Wert vom Typ TRIGGER zurückgeben.
Hier bieten sich NEW oder OLD an ...
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen