Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi INSERTs verbinden (https://www.delphipraxis.net/165681-inserts-verbinden.html)

himitsu 11. Jan 2012 10:30

Datenbank: Postgres • Version: 9? • Zugriff über: DevExpress oder so

INSERTs verbinden
 
SQL-Code:
INSERT INTO ... RETURNING mr_id;
oder?
INSERT INTO ... RETURNING mr_id AS mrID;
SQL-Code:
INSERT INTO ... VALUES
  (mrID, ...),
  (mrID, ...),
  ...;
Im Prinzip könnte ich ja das erste Insert in das Zweite reinbekommen, aber wie mache ich es, wenn ich den Wert mehrfach benötige? (temporäre Variablen gibt's scheinbar nicht)



Oder kann man vielleicht beim INSERT irgendwie angeben, daß bei jedem Record ein zusätzliches Feld mit diesem Wert gesetzt werden soll?
SQL-Code:
quasi statt
INSERT INTO t (i, a, b, c) VALUES (mrID, 'a', 'b', 'c'), (mrID, 'a', 'b', 'c')
sowas
INSERT INTO t (a, b, c) VALUES ('a', 'b', 'c'), ('a', 'b', 'c') ÜBERALL i = mrID

Bummi 11. Jan 2012 11:05

AW: INSERTs verbinden
 
Ich habe keine Ahnung von Postgres,
beim MS-SQL-Server ginge es so
Code:
Insert into Nase ([Spalte 0],[Spalte 1],[Spalte 2])
Select 1,'text1',1.1
union
Select 2,'text2',2.2
union
Select 3,'text3',3.3

himitsu 11. Jan 2012 11:22

AW: INSERTs verbinden
 
Nur kann ich da nicht erkennen, wo der mehrfach verwendete Wert reinkommt?

Für eine Zeile wäre es etwa so.
SQL-Code:
INSERT INTO t (a, b, c, i) VALUES ('a', 'b', 'c', (INSERT INTO ... RETURNING mr_id))
.
Aber ich möchte die ID ja an mehreren Stellen verwenden.

jobo 11. Jan 2012 11:34

AW: INSERTs verbinden
 
Ich versteh Dein Problem nicht ganz.
MR_ID müsste doch mit einer der Spaltennamen übereinstimmen und macht m.E. nur Sinn, wenn dieser Wert durch die DB/ Trigger/ Default automatisch belegt wird. Zumindest wenn es ein dynamischer "OUT" Parameter sein soll.
Wenn es bloß eine "IN"-Konstante für mehrere Zeilen ist, kannst Du sie doch explizit in das Statement eintragen.

P.S: Hab auch keine Ahnung von Postgres.

himitsu 11. Jan 2012 12:19

AW: INSERTs verbinden
 
mr_id ist ein AutoInc-Field.

Im Prinzip geht es um sowas:
SQL-Code:
CREATE TABLE Personen (
  Person  SERIAL PRIMARY KEY,
  Name    VARCHAR(50) NOT NULL);

CREATE TABLE Körperteil (
  Person  INTEGER NOT NULL REFERENCES Person ON UPDATE CASCADE,
  Name    VARCHAR(50) NOT NULL,
  Größe   INTEGER NOT NULL);



pID := INSERT INTO Personen (Name) VALUES ('Frank') RETURNING PersonId;
INSERT INTO Körperteile (Person, Name, Größe) VALUES (:pID, 'Nase', 10), (:pID, 'Mund', 20), (:pID, 'Augen', 5);

-- bzw.
pID := INSERT INTO Personen (Name) VALUES ('Frank') RETURNING PersonId;
INSERT INTO Körperteile (Person, Name, Größe) VALUES (:pID, 'Nase', 10);
INSERT INTO Körperteile (Person, Name, Größe) VALUES (:pID, 'Mund', 20);
INSERT INTO Körperteile (Person, Name, Größe) VALUES (:pID, 'Augen', 5);
...
Nur eben am Ende nur als ein einziges Statement.

Innerhalb von diesen komischen Prozeduren ginge sowas, aber in einer einfachen Query sieht es mit Variablen etwas schlecht aus.
SQL-Code:
CREATE FUNCTION ... AS #
DECLARE mrID INTEGER;
BEGIN
  SELECT mr_id INTO mrID FROM ...;
 
  INSERT INTO table VALUES (mrID, 'Nase', 10), (mrID, 'Mund', 20);
END#;

DeddyH 11. Jan 2012 12:24

AW: INSERTs verbinden
 
Also für jeden Datensatz den automatisch vergebenen Wert? Wenn ich es richtig gelesen habe, kann PostreSQL in Stored Procedures ganze Datenmengen zurückgeben. Wie man da nun aber auch Datenmengen als Eingabeparameter übergeben könnte, weiß ich leider auch nicht.

himitsu 11. Jan 2012 12:33

AW: INSERTs verbinden
 
Zitat:

Zitat von DeddyH (Beitrag 1145389)
Also für jeden Datensatz den automatisch vergebenen Wert?

Jupp.

Einen Wert/eine Stelle kann ich ersetzen, aber eben nicht Mehrere.

jobo 11. Jan 2012 12:44

AW: INSERTs verbinden
 
Also wenn es darum geht, dass Du Dir sparen willst, den Parameter im InsertQueury mehrfach zu bestücken, dann könnte man evtl. so vorgehen:

In Delphi Query SQL anonymous block in psql mit Variablen Declaration erzeugen, Variable einmalig mit Parameter bestücken und abfeuern.

So mach ich das zumindest in Oracle. Postgress soll ja "halbwegs" ähnlich sein. Obs geht weiß ich nicht, auf die Schnelle habe ich sowas hier gefunden:

http://blog.endpoint.com/2010/09/ano...de-blocks.html

Ob es das richtige ist und in Deiner Postgres Version auch geht, musst Du schauen.

himitsu 11. Jan 2012 13:43

AW: INSERTs verbinden
 
Cool, das mit dem Anonymus funktioniert. :thumb:

SQL-Code:
DO $$
DECLARE mrID INTEGER;
BEGIN
 
END$$;
Ich hatte es schon mit einer ähnlichen (krankeren) Variante versucht.
> StroredProzedur erstellen, aufrufen und wieder löschen
Nur ist das nicht grade "schön". :oops:

jobo 11. Jan 2012 13:54

AW: INSERTs verbinden
 
Fein!

Gegen eine StoredProc spricht ja eigentlich auch nichts, ich mein, wenn man sie nicht ständig erzeugt und wieder löscht.

Aber ich glaub, ich muss mir postgres auch mal anschauen.
Wenn sowas geht, gefällt mir das doch erst recht.

Und krank find ich jetzt anonymous block nicht grad. Wenn man unbedingt keine stored procs nutzen will, ist es doch ne schöne Alternative.

himitsu 11. Jan 2012 14:47

AW: INSERTs verbinden
 
Mit "krank" meinte ich die StoredProc.
Die Anonymus-Variante ist dagegen ganz hübsch.

Blöd wäre hier halt, wenn z.B. zur selben Zeit zwei solche Querys laufen und sie sich gegenseitig diese Prozedur überschreiben. :stupid:


Genausu wie eine zusätzliche Tabelle zu nutzen, für die temporären Variablen, auch dabei könnten sich welche gegenseitig diese Variable überschreiben.


Und das ständig Erstellen und Löschen *hust*
SQL-Code:
CREATE OR REPLACE FUNCTION temp_import()
  RETURNS INTEGER
  LANGUAGE plpgsql
  VOLATILE
  AS $BODY$
    DECLARE mrID INTEGER;
    BEGIN

      -- mach was

      RETURN true;
    END
  $BODY$;

SELECT temp_import();

DROP FUNCTION temp_import();
Dagegen sieht es als Anonymus dann doch schon besser aus.
SQL-Code:
DO $BODY$
  DECLARE mrID INTEGER;
  BEGIN

    -- mach was

  END
$BODY$ LANGUAGE plpgsql;

jobo 11. Jan 2012 15:23

AW: INSERTs verbinden
 
als ich nach dem anonymen Verfahren gegoogelt hab, bin ich auch auf ne Stored Proc gestoßen, der man sozusagen einen anonymen Block übergeben kann. Das stammt wohl noch aus Zeiten, wo Postgres nicht "anonym" konnte.
Vlt. ist das ja auch noch was für Dich.

Das Verfahren nutze ich unter Oracle gelegentlich, weil es 100% Zugriff auf allen DB Schnickschnack bietet. Konzeptionell ist es vlt fragwürdig, aber das muss jeder selbst entscheiden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz