Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   ALTER PROCEDURE mit ZeosLib aus Delphi auslösen (https://www.delphipraxis.net/187728-alter-procedure-mit-zeoslib-aus-delphi-ausloesen.html)

Siggi 27. Dez 2015 20:58

Datenbank: Firebird • Version: 2.5 • Zugriff über: ZEOSLib

ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Hallo zusammen,

nach stundenlangem erfolglosem Probieren und Googeln frage ich mal hier ob jemand eine Lösung kennt.

Der folgende Code funktioniert mit IBExpert problemlos (Hinweis: die Procedure macht derzeit nichts wirklich sinnvolles, ich möchte aber für meine Applikation zukünftig auch Updates der Datenbank per Script ausliefern können und versuche, diese Möglichkeoit zu implementieren. Die Procedure ist also nur ein Test, nichtsdestotrotz sollte sie funktionieren...):
Code:
SET TERM ^ ;
CREATE OR ALTER PROCEDURE TMP_UPDATE_DB
AS
Declare v_version integer;
BEGIN
  select DATABASE_VERSION from SETTINGS where ID=1 into v_version;

  if (not exists(
      select 1 from RDB$RELATION_FIELDS rf
      where rf.RDB$RELATION_NAME = 'TMP_TEST' and rf.RDB$FIELD_NAME = 'SPALTE5')
      ) then execute statement 'ALTER TABLE TMP_TEST ADD SPALTE5 VARCHAR(200)';

  if (:v_version < 2) then
    execute statement 'ALTER TABLE TMP_TEST ADD SPALTE6 VARCHAR(200)';

  if (:v_version > 3) then
    execute statement 'ALTER TABLE TMP_TEST ADD SPALTE7 VARCHAR(200)';
END ^
SET TERM ; ^
Mit der Komponente TZSQLProzessort der ZEOS-Lib bekomme ich aber die Fehlermeldung
Zitat:

SQL Error: unsuccessful metadata update MODIFY RDB$PROCEDURES failed. Error Code: -607. This operation is not defined for system tables. The SQL: CREATE OR ALTER PROCEDURE TMP_UPDATE_DB
AS
Declare v_version integer;
BEGIN
select DATABASE_VERSION from SETTINGS where ID=1 into v_version;

if (not exists(
select 1 from RDB$RELATION_FIELDS rf
where rf.RDB$RELATION_NAME = 'TMP_TEST' and rf.RDB$FIELD_NAME = 'SPALTE5')
) then execute statement 'ALTER TABLE TMP_TEST ADD SPALTE5 VARCHAR(200)';

if (:v_version < 2) then
execute statement 'ALTER TABLE TMP_TEST ADD SPALTE6 VARCHAR(200)';

if (:v_version > 3) then
execute statement 'ALTER TABLE TMP_TEST ADD SPALTE7 VARCHAR(200)';
END
;
Die SET TERM Zeilen haz TZSQLProcessor ausgeschnitten und nur das eigentliche CREATE OR ALTER PROCEDURE ausgeführt - evtl. ist das die Ursache??

Der Aufruf sieht so aus:
Delphi-Quellcode:
    ZSQLProcessor1.Delimiter:='^';
    ZSQLProcessor1.DelimiterType:= dtSetTerm;
    ZSQLProcessor1.LoadFromFile(ExtractFilePath(ParamStr(0))+'\SQL_UPDATE.sql');
    ZSQLProcessor1.CleanupStatements; // Kommentare entfernen
    ZSQLProcessor1.Parse;
    if(ZSQLProcessor1.StatementCount>0) then
    begin
      ZConnection1.StartTransaction;
      try
        ZSQLProcessor1.Execute;
        ZConnection1.Commit;
      except
        ZConnection1.Rollback;
      end;
    end;
Ich habe bereits andere Delimiter versucht, mit ";" z.B wird das Zusammenbauen der zu übergebenden Scripts gleich beim ersten ; abgebrochen.
Irgendeine Kleinigkeit übersehe ich da und finde es nicht :-(

Hat jemand einen Tipp?
Braucht Ihr weitere Infos?

Danke und Grüße,
Siggi

Perlsau 28. Dez 2015 01:54

AW: ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Moin

Die Meldung This operation is not defined for system tables ist wohl etwas irreführend, denn ich löse diesen Fehler auch dann aus, wenn ich z.B. versuche, eine Tabelle zu löschen, auf die in derselben DB existierende Views, Procedure, Trigger oder Generatoren verweisen. Auch kann man eine Tabelle wohl nicht ändern, so lange sie aktiv in Verwendung ist, sprich: In deiner Anwendung besteht eine aktive Verbindung zu dieser Tabelle, die du gerade zu ändern versuchst. Du kannst das überprüfen, indem du versuchst, deine SQL-Anweisung mit IbExpert auszuführen, während deine Anwendung läuft. In diesem Fall müßtest du dieselbe Fehlermeldung in IbExpert erhalten.

Siggi 28. Dez 2015 07:52

AW: ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Ja, die Meldung ist leider bei vielen (allen?) Fehlern mit DDL-Befehlen identisch und hilft nicht viel weiter - meist sieht man zwar im enthaltenen SQL einen Fehler, hier ist das aber leider nicht so.
Aber die Stored-Procedure wird hier nur angelegt / verändert und nicht ausgeführt (es können also keine Tabellen gesperrt sein bzw. selbst wenn wäre es egal) und sie ist zum Zeitpunkt der Ausführung der ALTER PROCEDURE nicht aktiv. Mit IBEXPERT kann ich die PROCEDURE auch dann ändern, wenn ich gerade im Debugger genau vor der Ausführung von ZSQLProcessor1.Execute stehe und ebenso, wenn dort gerade die Ausführung im EXCEPT-Block angekommen ist.

hoika 28. Dez 2015 08:11

AW: ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Hallo,

setze mal ParamCheck auf False

(http://zeoslib.sourceforge.net/viewtopic.php?t=2993)


Heiko

Siggi 28. Dez 2015 08:46

AW: ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Das macht leider auch keinen Unterschied :cry:
und auch wenn es wenig erfolgversprechend war habe ich zusätzlich mal die Komponente vom Formular entfernt und erst zur Laufzeit erzeugt, was natürlich auch keinen Unterschied ausmacht.
ZEOS verwendet intern
Delphi-Quellcode:
    GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle,
      @StmtHandle, GetDialect, FParamSQLData.GetData);
und das Statement an sich sieht dabei völlig richtig aus.

Siggi 28. Dez 2015 11:26

AW: ALTER PROCEDURE mit ZeosLib aus Delphi auslösen
 
Habe mir mal den FB Trace Manager von Upscene als Trial installiert und damit den Fehler gefunden. Der Fehler saß wie immer vor der Tastatur :oops:. In der Applikation arbeite ich mit einem DB-User mit eingeschränkten Rechten. Für das ALTER PROCEDURE sind natürlich volle Zugriffsrechte notwendig. Ein einfaches Schließen der DB-Session und Anmelden als sysdba vor dem Ausführen des Scripts hat das Problem gelöst :roll:.

Danke für alle Hilfeversuche und vielleicht hilft der Thread ja zukünftig mal jemandem der genauso auf der Leitung steht.
Als Tipp: der Trace Manager war in diesem Fall sehr hilfreich, da er nicht nur "unseccessfull metadta update" ausgegeben hat sondern auch einen Fehler bezüglich der persmissions (habe den gerade nicht mehr im exakten Wortlaut). Damit war's dann einfach zu lösen :-D

Viele Grüße,
Siggi


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:26 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