![]() |
Datenbank: postgres • Version: 10.4 • Zugriff über: unidac
Column "xxx" specified more than once
Hi Zusammen,
ich führe gerade eine Append auf eine Tabelle aus und er behauptet "Column 'xxx' specified more than once". Das macht meiner Meinung nach bei einer einzelnen Tabelle bzw. bei einem Append keinen Sinn. Weiß jemand zufällig wie ich mir die tatsächlich abgeschickte SQL (ich gehe mal davon aus, dass hier eine SQL generiert wird) ausgeben lassen kann, damit ich wenigstens sehe was passiert? Verrückt ist auch folgendes: In der Tabelle sind alle Felder klein geschrieben. Alle Felder werden in der Originalschreibweise angesprochen. Ändere ich den Befehl von
Delphi-Quellcode:
auf
APFAMPRU_SQL['Verfalldatum'] := DateAsNull(edVerfall.Date);
Delphi-Quellcode:
(also mit kleinem "V") dann geht es.
APFAMPRU_SQL['verfalldatum'] := DateAsNull(edVerfall.Date);
Die Zeile
Delphi-Quellcode:
stört ihn hierbei also von der Groß-/Kleinschreibung nicht!
APFAMPRU_SQL['Status'] := nStatus;
Wenn er bei allen Feldern meckern würde, wäre das ja klar. Dann wäre das einfach nur ein komischer/falscher Fehlertext. Aber diese Konstellation verwirrt mich. PS: Ich habe gerade nochmal nachgesehen; Es gibt tatsächlich nur ein Feld mit diesem Namen! :lol: Verwende Delphi 10.3.2 mit Devart UniDac 8.1.3. Vielen Dank schonmal für die Zeit und Hilfe! Liebe Grüße Incocnito |
AW: Column "xxx" specified more than once
Hallo,
ich würde Dir von der Nutzung der TTable-Komponenten abraten. Bau eine passende Query, dann siehst Du auch, was an die DB geht. PS: DevArt müsste auch eine TDBMonitor haben, dort kannst Du dir die geschickten Queries ansehen. |
AW: Column "xxx" specified more than once
Zitat:
Zitat:
Ich vermute, daß da soetwas wie
Code:
generiert wird.
update table1 set field1=x,set field2=y,set field1=z
(die genae Syntax ist natürlich von Deiner DB abhängig) Gruß K-H |
AW: Column "xxx" specified more than once
Probleme mit Großkleinschreibung rühren meist daher, dass im Table Create Script Hochkomma o.ä bei der Feldbenennung verwendet wurden.
Wo "findest Du die Felder in Kleinschrift"? Schau Dir als erstes das Create Script an. |
AW: Column "xxx" specified more than once
Nachtrag:
für Windows, Postgres 12, deutsch, Standardinstallation Konfiguration von Postgres anpassen, um bestimmte oder alle SQL Statements zu loggen: C:\Program Files\PostgreSQL\12\data\postgresql.conf Zeile:
Code:
Kommentarzeichen entfernen und Eintrag 'none' entsprechend der Auflistung / Bedarf anpassen.
..
#log_statement = 'none' # none, ddl, mod, all .. Z.B. 'mod' (Später wieder zurückstellen, sonst kann es schnell voll werden im System!)
Code:
stderr ist ein Defaulteintrag, der bedeutet, dass die tatsächlich verwendeten Logfiles in der folgenden Datei explizit zu finden sind (nicht nur ein Verzeichnis):
..
# - Where to Log - log_destination = 'stderr' .. C:\Program Files\PostgreSQL\12\data\current_logfiles Dabei wird jeweils das konkrete, aktuell verwendete Logfile mit Tagesdatum aufgeführt. Man landet in der Regel hier: C:\Program Files\PostgreSQL\12\data\log\ Die Logfiles enthalten im Fehlerfall sowieso bereits SQL Statement Text und der Loglevel muss nicht geändert werden. z.B.
Code:
hier sind die Logging Infos (verwendete Version beachten!):
..
2020-03-14 08:09:59.324 CET [5416] FEHLER: Spalte »t_id« existiert nicht bei Zeichen 8 2020-03-14 08:09:59.324 CET [5416] TIPP: Vielleicht wurde beabsichtigt, auf die Spalte »test.´t_id´« zu verweisen. 2020-03-14 08:09:59.324 CET [5416] ANWEISUNG: select t_id from test .. ![]() (btw: Postgres bietet schon seit langer Zeit diese vorbildliche, versionierte Doku) |
AW: Column "xxx" specified more than once
Danke erstmal für die ganzen Ideen/Einwürfe!
Zitat:
2) Ich soll in unserem Hauptprojekt die Datenbank ersetzen, dabei versuche ich so wenig Quelltext wie möglich zu ändern. Und da das bisher über Tabellen-Objekte lief, baue ich das so um, dass es ebenfalls wieder so läuft. ... Naja, das ist das Ziel! Zitat:
scheinbar, denn er speichert die SQL nur, wenn ich den Feldnamen kleingeschrieben habe. Schreibe ich das Feld groß, so zeigt er mit die erzeugte SQL nicht an. Zitat:
Zitat:
Ich habe das Log dann in der Windows-Ereignisanzeige gefunden:
Code:
Ich würde sagen, dass die Komponente da Mist baut, oder?
2020-03-16 12:05:46.541 CET [6356] ERROR: column "verfalldatum" specified more than once at character 151
2020-03-16 12:05:46.541 CET [6356] STATEMENT: INSERT INTO some_sheme.some_table (charge, pruefungsdatum, herstellungsdatum, lfdnr, pruefer, pzn, status, verfalldatum, verfalldatum, verfalldatum, verfalldatum) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) In Zusammenhang mit dem ersten Zitat würde ich aber trotzdem schauen, dass ich das ans Laufen bekomme. Das komplette Projekt auf Querys umzubauen wäre der Horror. Liebe Grüße an alle Incocnito |
AW: Column "xxx" specified more than once
Hallo,
hast du auf dem Form da irgendwelche datensensitiven Elemente (TDBGrid), wo Du Spalteneigenschaften angepasst hast (Displayformat oder sowas)? Such mal in der DFM nach den doppelten Spaltennamen. |
AW: Column "xxx" specified more than once
Die Komponente wird zur Laufzeit erstellt ohne Parent.
Diese wird dann auf dem Formular an mehreren Stellen benutzt. Erzeuge ich eine neue Komponente und arbeite darauf, dann geht's. Fehlersuche geht weiter ... |
AW: Column "xxx" specified more than once
Das klingt ganz leicht nach timing / initialisierungsfehler.
Aber ohne originalen Code ist es Raterei. |
AW: Column "xxx" specified more than once
Falls du nicht doch selber bei dir einen Fehler findest und ihr einen laufenden Vertrag bei DevArt habt, kann es sich lohnen, dort mal beim Support anzufragen. Ich hatte in den letzten Wochen zwei Probleme (eins lag letztlich an mir, eins war tatsächlich ein Bug in UniDac) und in beiden Fällen innerhalb weniger Stunden eine hilfreiche Antwort bekommen.
|
AW: Column "xxx" specified more than once
Ich habe da mal was gebaut, mit dem das jeder nachvollziehen könnte.
Man muss natürliche eine PostgreSQL-Datenbank haben und eine neue Datenbank samt Benutzer anlegen.
Delphi-Quellcode:
Hatte ich mein Tabellen-Objekt also beim Filtern um das Execute erweitert,
unit TemporaererTestGF;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Uni; { -- Table: test_sh.fam_pruefung -- DROP TABLE test_sh.fam_pruefung CREATE TABLE test_sh.fam_pruefung ( bemerkung text COLLATE pg_catalog."default", charge character varying(20) COLLATE pg_catalog."default", data text COLLATE pg_catalog."default", pruefungsdatum date, herstellungsdatum date, lfdnr integer, massnahme text COLLATE pg_catalog."default", pruefer character varying(5) COLLATE pg_catalog."default", pzn integer, status integer, verfalldatum date ) WITH ( OIDS = FALSE ) TABLESPACE pg_default; ALTER TABLE test_sh.fam_pruefung OWNER to testuser; GRANT ALL ON TABLE test_sh.fam_pruefung TO testuser; GRANT ALL ON TABLE test_sh.fam_pruefung TO postgres; } type TfrmTemporaererTestGF = class(TForm) btnRun: TButton; pnlButtons: TPanel; btnClose: TButton; procedure btnCloseClick(Sender: TObject); procedure btnRunClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var frmTemporaererTestGF: TfrmTemporaererTestGF; implementation uses DB; {$R *.dfm} procedure TfrmTemporaererTestGF.btnCloseClick(Sender: TObject); begin Close(); end; procedure TfrmTemporaererTestGF.btnRunClick(Sender: TObject); var xnPZN : Integer; nLfdNr : Integer; APFAMPRU_SQL : TUniTable; DBCon : TUniConnection; begin DBCon := TUniConnection.Create(nil); DBCon.ProviderName := 'PostgreSQL'; DBCon.Options.LocalFailover := True; DBCon.SpecificOptions.Add('ApplicationName=TestGF'); DBCon.Database := 'test_db';//DBGloApo.FDConnection.Database; DBCon.Username := 'testuser';//DBGloApo.FDConnection.Username; DBCon.Password := 'test_12345';//DBGloApo.FDConnection.Password; DBCon.Server := 'localhost';//DBGloApo.FDConnection.Server; DBCon.Port := 9999;//DBGloApo.FDConnection.Port; DBCon.Connected := True; APFAMPRU_SQL := TUniTable.Create(Application.MainForm); APFAMPRU_SQL.Connection := DBCon; APFAMPRU_SQL.TableName := 'test_sh.fam_pruefung';//TPostgres.SchemaNameAposoft + '.' + 'fam_pruefung'; APFAMPRU_SQL.OrderFields := 'PZN, Pruefungsdatum'; APFAMPRU_SQL.Open(); try APFAMPRU_SQL.OrderFields := 'LfdNr'; APFAMPRU_SQL.Last(); nLfdNr := APFAMPRU_SQL.FieldByName('LfdNr').AsInteger + 1; APFAMPRU_SQL.OrderFields := 'PZN, Pruefungsdatum'; // ---- xnPZN := 9206022; if (APFAMPRU_SQL.Locate('PZN', VarArrayOf([xnPZN]), [])) then begin APFAMPRU_SQL.Filter := 'PZN = ' + xnPZN.ToString; APFAMPRU_SQL.Filtered := True; // <- Diese Zeile ist das Problem!? APFAMPRU_SQL.Execute(); // Mit Execute geht alles! APFAMPRU_SQL.Filtered := False; APFAMPRU_SQL.Execute(); // Mit Execute geht alles! end; APFAMPRU_SQL.Append(); APFAMPRU_SQL['PZN'] := xnPZN; APFAMPRU_SQL['Pruefungsdatum'] := EncodeDate(2020, 4, 3); APFAMPRU_SQL['Charge'] := '111'; APFAMPRU_SQL['Herstellungsdatum'] := EncodeDate(2020, 1, 1); APFAMPRU_SQL['Verfalldatum'] := EncodeDate(2020, 12, 31); APFAMPRU_SQL['Status'] := 1; APFAMPRU_SQL['Pruefer'] := 'gfr'; APFAMPRU_SQL['LfdNr'] := nLfdNr; APFAMPRU_SQL.Post(); finally try APFAMPRU_SQL.Free(); except end; try DBCon.Free(); except end; end; end; end. lief alles problemlos. Ein wenig seltsam finde ich das aber schon. Vor allem, dass es so ein bisschen geht. 1) Wenn "Verfalldatum" klein geschrieben ist (nur das Rest ist egal) 2) Nach Filtern mit "Execute" PS: Nicht wie ich darauf reinfallsen: Beim ersten Mal läuft es ja, weil er das Filtern nicht ausführt! PS2: Den Port und evtl. den Server müsst ihr natürlich auch für euch anpassen! PS3: Leider habe ich keine Zeit dem weiter nachzugehen. Falls mal jemand etwas ähnliches hat, hilft dieser Trick aber ja. LG Incocnito |
AW: Column "xxx" specified more than once
Zitat:
Es wird automatisch ein Lowercase über alles gelegt, außer bei 'Strings' und "Namen" mit " . Zitat:
Und dann gibt es den Fall, dass eine Spalte mehrfach im Select vorkommt, z.B. nochmal mit AS umbenannt.
Delphi-Quellcode:
oder bei
SELECT aaa, aaa AS bbb
Delphi-Quellcode:
bzw,
SELECT aaa, *
Delphi-Quellcode:
.
SELECT aaa AS bbb, *
Hier gibt es erstmal kein Problem, aber wenn das Feld geändert wurde und man das POSTen will, dann weiß die DBKompoente nicht welchen Wert die nun speichern soll. Den Wert von aaa oder den von bbb, welcher ja auch in aaa gespeichert würde. Lösung:
Wie UniDAC hier nun clientseitig arbeitet .... wer weiß, aber vermutlich auch so wie PgDAC, welches die Vegleiche der Namen case-insensitiv durchführt, womit clientseitig das eigentlich auch egal wäre. Hast du mal nachgesehn, wie es in der Datnbank aussieht? Wurden die Felder Verfalldatum oder Status dort eventuell wirklich explizit mit Großschreibung erstellt? PS: Bei nur einem Feld, wäre beim Locate der Weg über das Variant-Array nicht nötig.
Delphi-Quellcode:
APFAMPRU_SQL.Locate('PZN', VarArrayOf([xnPZN]), ...) = APFAMPRU_SQL.Locate('PZN', xnPZN, ...)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz