Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   DROP CONSTRAINT nicht mit Namen (https://www.delphipraxis.net/213152-drop-constraint-nicht-mit-namen.html)

BlueStarHH 6. Jun 2023 08:57

Datenbank: Firebird • Version: 3.x • Zugriff über: IBDAC

DROP CONSTRAINT nicht mit Namen
 
Hallo,

ich möchte ein CONSTRAINT löschen. So würde ich es normalerweise machen:

Code:
ALTER TABLE KUNDE DROP CONSTRAINT INTEG_356;
Jetzt kenne ich den Namen des CONSTRAINTs jedoch nicht. Der Name kann in unterschiedlichen Datenbanken unterschiedlich sein. Ich kenne nur den Ausdruck des CONSTRAINTs. Es müsste doch über die Systemtabellen möglich sein, über den Ausdruck des CONSTRAINTs an den Namen des CONSTRAINTs zu kommen?

In der Tabelle RDB$RELATION_CONSTRAINTS sehe ich jedoch nur den Namen in RDB$CONSTRAINT_NAME. Wo finde ich den Ausdruck? Danke!

BlueStarHH 6. Jun 2023 09:26

AW: DROP CONSTRAINT nicht mit Namen
 
Habe es nun selbst gefunden. So komme ich an den Namen:

Code:
select distinct(RDB$CONSTRAINT_NAME) from RDB$CHECK_CONSTRAINTS where RDB$TRIGGER_NAME in (
  select RDB$TRIGGER_NAME from RDB$TRIGGERS where RDB$RELATION_NAME = 'KUNDE' and RDB$TRIGGER_SOURCE = 'CHECK (AFIELD between 1 and 4)')
Aber wie kann ich den Namen nun in dieser SQL-Anweisung nutzen?

Code:
 ALTER TABLE KUNDE DROP CONSTRAINT _____
So geht es nicht:

Code:
ALTER TABLE KUNDE DROP CONSTRAINT (
 select distinct(RDB$CONSTRAINT_NAME) from RDB$CHECK_CONSTRAINTS where RDB$TRIGGER_NAME in (
  select RDB$TRIGGER_NAME from RDB$TRIGGERS where RDB$RELATION_NAME = 'KUNDE' and RDB$TRIGGER_SOURCE = 'CHECK (AFIELD between 1 and 4)')
)
Die Klammer ( ist unbekannt. Ohne Klammer mag er das erste select nicht.

lxo 6. Jun 2023 09:46

AW: DROP CONSTRAINT nicht mit Namen
 
Schau dir mal Execute Statement an.https://firebirdsql.org/refdocs/lang...-execstat.html

In Verbindung mit einem execute Block könntest du den Namen vorher selektieren in einer variable merken und dein alter table danach mit execute Statement ausführen.

BlueStarHH 6. Jun 2023 09:49

AW: DROP CONSTRAINT nicht mit Namen
 
Danke, hab das ganze nun in einen EXECUTE BLOCK gepackt. Damit klappt es:

Code:
SET TERM !! ;
EXECUTE BLOCK AS
  declare variable CName varchar(2000);
BEGIN
  execute statement 'select distinct(RDB$CONSTRAINT_NAME) from RDB$CHECK_CONSTRAINTS where RDB$TRIGGER_NAME in (
    select RDB$TRIGGER_NAME from RDB$TRIGGERS where RDB$RELATION_NAME = ''KUNDE'' and RDB$TRIGGER_SOURCE = ''CHECK (AFIELD between 1 and 4)'')' into :CName;

  if (:CName <> '') then
    execute statement 'ALTER TABLE KUNDE DROP CONSTRAINT ' || Trim(:CName) || ';';
END!!
SET TERM ; !!

Jetzt wundert mich nur der Hinweis aus der Firebird Hilfe, der sagt, dass ich keine DDL strings mit EXECUTE STATEMENT ausführen soll. Warum nicht? Ist das hier schlimm?

Zitat:

Although this form of EXECUTE STATEMENT can also be used with all kinds of DDL strings (except CREATE/DROP DATABASE), it is generally very, very unwise to use this trick in order to circumvent the no-DDL rule in PSQL.

lxo 6. Jun 2023 09:54

AW: DROP CONSTRAINT nicht mit Namen
 
Weiß nicht. Nutze das öfter und eigentlich keine Probleme damit.
Problematisch könnte nur sein wenn andere User mit der Datenbank verbunden sind. Dann könnte das alter Table fehlschlagen (Index is in use) oder so ähnlich.

Wenn ich an bestehenden Metadaten etwas ändere mach ich in der Regel aber immer ein shutdown, damit ist das Problem gegessen.

IBExpert 6. Jun 2023 09:58

AW: DROP CONSTRAINT nicht mit Namen
 
Zitat:

Zitat von BlueStarHH (Beitrag 1523107)
Jetzt wundert mich nur der Hinweis aus der Firebird Hilfe, der sagt, dass ich keine DDL strings mit EXECUTE STATEMENT ausführen soll. Warum nicht? Ist das hier schlimm?

Zitat:

Although this form of EXECUTE STATEMENT can also be used with all kinds of DDL strings (except CREATE/DROP DATABASE), it is generally very, very unwise to use this trick in order to circumvent the no-DDL rule in PSQL.

naja, hängt unter anderem mit transaktionseinstellungen zusammen und was du damit vorhast. Im Metadata Transaction mode könnte kann zum beispiel eine primary key constraint damit löschen, die dann aber wegen deiner metadata transaction einstellung isc_tbp_wait warten könnte, das irgendwann mal der pk von niemandem mehr benutzt wird, was aber evtl niemals passieren wird und du damit die gesamte Datenbank in einer Zustand versetzt der dein statement warten lässt, alle anderen clients aber schon mal beim schreiben blockiert.

Neue objekte damit erzeugen ist eigentlich nie ein problem, vorhanden ändern oder sogar löschen kann auf einer Live Datenbank schon blöde neben effekte haben. Wenn du aber exklusiven zugriff hast zB durch shutdown ist das gar kein problem das so zu machen, benutze ich ähnlich seit jahren und hab selten Problem, mach damit aber auch ganz selten mal drop


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