Einzelnen Beitrag anzeigen

Incocnito

Registriert seit: 28. Nov 2016
223 Beiträge
 
#11

AW: Column "xxx" specified more than once

  Alt 17. Apr 2020, 16:20
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:
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.
Hatte ich mein Tabellen-Objekt also beim Filtern um das Execute erweitert,
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
  Mit Zitat antworten Zitat