Tabellenzeile vim record auslesen

Hi,

ich bin es schon wieder :slight_smile: .
Bin dabei Zeilen einer Tabelle auszulesen und in einer andere einzufügen. Die Tabellendefinitionen sind identisch. Habe auch testweise die selbe Tabelle beim Auslesen und Einfügen verwendet. Manchmal klappt das Auslesen hinsichtlich des verwendeten Datentyps und manchmal nicht. Da wird varchar nicht als varchar ausgelesen und das gibt dann Porbleme beim Einfügen.

Das ist die Tabelle:

CREATE TABLE tabrdheader
(
  nhid bigint NOT NULL,
  cpartition character(4) NOT NULL,
  vcline character varying(80) NOT NULL,
  vccell character varying(80) NOT NULL,
  vcmodule character varying(80),
  vcswprojectname character varying(80),
  vcswprojectversion character varying(16),
  vcsetupdate timestamp without time zone NOT NULL,
  vclogicalid character varying(30) NOT NULL,
  vcphysicalid character varying(30),
  vcpartno character varying(50) NOT NULL,
  ntdrelease double precision NOT NULL,
  vcprocessingdate timestamp without time zone NOT NULL,
  vcprocessingcode character varying(10) NOT NULL,
  vcprocessresult character varying(10) NOT NULL,
  nprocesscycle double precision NOT NULL,
  nprocessparts double precision NOT NULL,
  dinsertdate timestamp without time zone NOT NULL
)

und hier der zugehörige Record einer Zeile:

723,0107,EHB1-1,"Kugel 3,5mm",,xxxx,"y.zz            ","1970-06-10 16:04:16.6",1541,102,0265250007-00,161,"2001-08-28 14:39:10.43",1,1,1,1,"2002-03-27 00:00:00"

Ich habe es auch schon mit ROWTYPE probiert, jedoch mit dem Selben Ergebnis.

Warum funktioniert das nicht?

mfg
Marcus

Wir wissen weder, was Du genau gemacht hast, noch welcher Fehler inkl. Fehlermeldung aufgetreten ist.


Andreas

oh nein!!! :smiley:

Das ist die Funktion. Ich bekomme dann den Fehler, dass bei einigen Spaltenwerten der Datentyp nicht passt, um ein Insert durchzuführen. Mittels record sollten doch die Datentypen passen, wenn ich sie auslese. Der Sinn oder Unsinn der Funktion sei mal außer Acht gelassen.

-- Function: hs2k_migration."update"()

-- DROP FUNCTION hs2k_migration."update"();

CREATE OR REPLACE FUNCTION hs2k_migration."update"()
  RETURNS character varying AS
$BODY$
DECLARE
    dauer integer;
    erg_tabrdheader record;
    erg_test tabrdheader%ROWTYPE;
    test tabrdheader.vcline%Type;
BEGIN

    FOR erg_test IN select * from tabrdheader_0107 LOOP
    
--    FOR erg_tabrdheader IN select * from tabrdheader_0107 LOOP
        RAISE NOTICE 'ERGEBNIS: %', erg_test;
        RAISE NOTICE 'ERGEBNIS: %', test;
        
    --    RAISE NOTICE 'ERGEBNIS: %', erg_tabrdheader;
    --    EXECUTE 'Insert into tabrdheader_0107 values '
    --    || erg_tabrdheader;
         
        ENd LOOP;
        
    EXECUTE 'Delete from tabrdheader_0908';

    RETURN 'ENDE';
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION hs2k_migration."update"() OWNER TO hs2k;

mfg
Marcus

das problem ist folgendes:

select row('hallo',[color=Red]null[/color],1)

ergibt

"(hallo,,1)"

du kannst die text-repräsentation fuer diese row so nicht einfach als input fuer dynamisches sql benutzen

ja für die leere Spalte null würde ich mir was einfallen lasen, aber komisch ist, dass der Datentyp varchar mal mit Apostrophe und mal ohne Apostrophe drin ist. Das ist das große Problem. Wenn ich den String dann noch ändere vor dem Einfügen, weiß ich ja nicht, ob der 3. Datenwert jetzt ein varchar ist oder nicht.

mfg
Marcus

verwende doch einfach statisches SQL

einfach INSERT INTO tablexyz VALUES rowVariable;

ohne execute davor

Deine Daten enthalten Zeichen, die mißverstanden werden könnten, daher die unterschiedlichen Darstellungen.

Das, was Deine function da macht, ist mit einem SQL-Einzeiler auch und besser lösbar.

Andreas

Funktioniert leider auch nicht. Grund ist wieder der Datentyp.


Ich dachte der liest den Datentyp direkt aus und versucht nicht anhand der darin enthaltenen Zeichen diesen zu interpretieren. Das selbige gilt für Type und RowType?

Meinst mit einem Update? Weiteren Tip?

mfg
Marcus

dann sind deine tabellen nicht identisch - folge einfach dem fehler oder dem weissen kaninchen

kontrolliere das doch bitte mal - auch ob die “natuerliche reihenfolge” der attribute in beiden tabellen gleich ist!

ak meint du kannst auch einfach so die daten uebertragen
INSERT INTO target
SELECT * FROM source
WHERE condition;

diese loops sind an dieser stelle nicht geeignet

ich füge ja Testweise in die selbe Tabelle ein, aus der ich die Datensätze zuvor hole.

Die Funktion ist noch nicht vollständig. Nach dem Select sollen die Datensätze modifiziert werden und dann in eine andere Tabelle eingefügt weren.

mfg
Marcus

zeig doch mal den aktuellen versuch ohne EXECUTE mit statischen SQL der da schief geht

fürs näxte mal - am besten gleich code liefern wenn was nicht geht

Geht klar, werde ich zukünftig beachten


-- Function: hs2k_migration."update"()

-- DROP FUNCTION hs2k_migration."update"();

CREATE OR REPLACE FUNCTION hs2k_migration."update"()
  RETURNS character varying AS
$BODY$
DECLARE

    erg_tabrdheader record;
    erg_test tabrdheader%ROWTYPE;
    test tabrdheader.vcline%Type;
BEGIN
    
    
    FOR erg_tabrdheader IN select * from tabrdheader_0107 LOOP
    --    RAISE NOTICE 'ERGEBNIS: %', erg_test;
    --    RAISE NOTICE 'ERGEBNIS: %', erg_tabrdheader;
    --    EXECUTE 'Insert into tabrdheader_0107 values '
    --    || erg_tabrdheader;
    
   Insert into tabrdheader_0107 values (erg_tabrdheader); 

   END LOOP;
   
        
    EXECUTE 'Delete from tabrdheader_0908';
*/
    RETURN 'ENDE';
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION hs2k_migration."update"() OWNER TO hs2k;


-- select hs2k_migration.update();

Fehlermeldung:

FEHLER: Spalte »nhid« hat Typ bigint, aber der Ausdruck hat Typ record
LINE 1: Insert into tabrdheader_0107 values ( $1 )
^
HINT: Sie müssen den Ausdruck umschreiben oder eine Typumwandlung vornehmen.
QUERY: Insert into tabrdheader_0107 values ( $1 )
CONTEXT: PL/pgSQL function “update” line 30 at SQL-Anweisung

mfg
Marcus

argh … hatte ich in meinem beispiel eine klammer um die rowVariable? :smiley:

bei dem anfaenglichen code von dir - wo du EXECUTE verwendet hattest - hast du auch keine klammer verwendet, weil du gesehen hast, dass die “klammer” da irgendwie mit drin ist …

einfach … VALUES rowVariable … und nicht VALUES (rowVariable)

diese klammerung erzeug eine feldliste … daher sind die elemente dazwischen jeweils als einzelnes attribut zu verstehen - der erste wert muss den typ des ersten attributes deiner table haben … der ist biging - und du versuchst diesem eine record-variable zuzuweisen -> siehe fehler

die klammer eroeffnet eine feldliste - daher nimmt er an dass nach dem klammerauf ein wert kommt - das erste feld in der table scheint vom typ bigint - und du setzt da die row ein … -> siehe fehler und verstehe ihn

Zu Anfang hatte ich auch keine Klammer drum. Da aber die folgende Fehlermeldung kam, hab ich es mit Klammern probiert:

FEHLER: Syntaxfehler bei »$1«
LINE 1: Insert into tabrdheader_0107 values $1
^
QUERY: Insert into tabrdheader_0107 values $1
CONTEXT: SQL statement in PL/PgSQL function “update” near line 30


********** Error **********

FEHLER: Syntaxfehler bei »$1«
SQL state: 42601
Context: SQL statement in PL/PgSQL function “update” near line 30

seltsam … ich war mir sicher, dass das geht - da muss ich nochmal forschen

das hier funktioniert auf jeden fall - aber diesmal wieder MIT klammerung :wink:

INSERT INTO … VALUES (recordVariable.*)

Ja, danke dir.

Sag mal, kann man in einem SQL file PL/pgSQL verwenden, oder ist das nur innerhalb von Funktionen möglich?

mfg
Marcus

in einem SQL script kannst du

  1. eine solche funktion erzeugen CREATE

  2. diese erzeugte funktion danach “ausfuehren” z.B. SELECT my_function()

“einfach so” wird in einem SQL file nix ausgefuehrt

Alles klar, danke dir. Dann muss es über eine Funktion gehen.

mfg
Marcus