Announcement

Collapse
No announcement yet.

FOREIGNKEY disablen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • FOREIGNKEY disablen

    Moin

    Bei einem Transferprogramm (noch mit Delphi7Enterprise und AnyDAC realisiert) werden die Tabellen mit TRUNCATE geleert, um die IDENTITY wieder auf den ursprünglichen Anfangswert zu setzen. Das funktioniert ja bekanntlich nur, wenn keine FOREIGNKEY-Contraints vorhanden sind.
    Okay, also werden die vorhandenen FOREIGNKEYs disabled - nur das funktioniert leider nicht wie erhofft/gewünscht.

    Folgende Vorgehensweise ist derzeit gecodet (nur die relevanten Teile hier eingestellt):
    Code:
    procedure TDMMSSQL.DISABLE_FK(const Tabelle: String; const disable: Boolean);
    var S: String;
        FK_Tabellen: TADQuery;
    begin
      if disable then S := 'NOCKECK' else S := 'WITH CHECK CHECK';
    ...
    {Fremdschlüssel und zugehörige Tabellen ermitteln}
    
      FK_Tabellen.SQL.Text := ('SELECT fk.name AS FK_NAME, so.name AS TAB_NAME  FROM sys.foreign_keys fk '+
                               'JOIN sys.objects so ON so.OBJECT_ID=fk.parent_object_id ' +
                               'WHERE referenced_object_id = OBJECT_ID(N''[dbo].[' + Tabelle +']'')');
    
    {Ausführungsanweisung zusammenbauen}
    ...
        while not FK_Tabellen.Eof do
        begin
          ADCmdDisableFK.CommandText.Append(Format('ALTER TABLE [dbo].[%s] %s CONSTRAINT %s ; ',
                                                   [FK_Tabellen['TAB_NAME'],
                                                    S,
                                                    FK_Tabellen['FK_NAME']]));
         FK_Tabellen.Next;
        end;
    ...
        ADCmdDisableFK.CommandKind := skExecute;
        ADCmdDisableFK.Prepare();
        ADCmdDisableFK.Execute();
    //--ADCmdDisableFK ist vom Typ TADCommand
    Das Statement sieht dann bsp. so aus:
    Code:
        ALTER TABLE WE_ADR NOCHECK CONSTRAINT FK_WE_ADR_ADRESSEN;
          ALTER TABLE ADRKONTAKT NOCHECK CONSTRAINT FK_ADRKONTAKT_ADRESSEN
    und soweit gesehen ja auch korrekt (!?)
    Allerdings meckert Delphi bzw die entsprechende AnyDAC-Komponente den Fehler:
    [AnyDac][Phys][ODBC][Microsoft][SQL Native Client][SQL Server]Falsche Syntax in der Nähe des 'CONSTRAINT'-Schlüsselwortes.
    Warum?Wieso? Was habe ich da übersehen? Dieses Statement exact so im SQL-ManagerStudio ausgeführt läuft ohne Meckerei

    Wenn ich das Statement jetzt direkt als CommandText hartcodiert eingebe, dann gibt es keinen Mecker - es wird anscheinend ausgeführt Aber nur anscheinend, denn ein nachfolgendes TRUNCATE ADRESSEN erzeugt den Fehler (sinngemäss): ... es sind noch FOREIGNKEY-Abhängigkeiten vorhanden...
    Ähm... was läuft da nicht richtig?
    Meine Fragen:
    1. Wo ist der Syntaxfehler im zusammengrbauten Statement?
    2. Warum wird das ExecuteKommando (in diesem Fall) nicht korrekt durchgeführt? Anm.: Andere Kommandos wie CREATE TABLE etc funktionieren anstandlos und korrekt

    Ist diese Vorgehensweise überhaupt sinnvoll oder sollte ich besser DROP FOREIGNKEY absetzen und anschliessend diese wieder neu erstellen??

    Bin dienstlich unterwegs, von daher könnten Reaktionen auf Antworten verspätet erfolgen...
    Mit freundlichem Gruß
    Rainer

  • #2
    Hallo,

    Wenn ich das Statement jetzt direkt als CommandText hartcodiert eingebe..
    Was passiert, wenn diese Anweisungen in eine Stored Procedure der Datenbank ausgelagert werden und das Delphi-Programm diese gespeicherte Prozeduren in einer separaten Datenbankverbindung ausführt? Die für den Transfer verwendet Datenbankverbindung wird erst dann geöffnet, wenn die CONTRAINs deaktiviert wurden.

    Comment


    • #3
      Moin
      Danke für die Antwort. Das mit ner SP hierfür kam mir nicht in den Sinn... Da das Transferprogramm eigentlich ja 'nur' die betagten Paradox-Tabellen ablösen soll werde ich da auch weiter keine grossartigen Experimente und Zeitaufwand reinstecken. Ich bin halt nur über die beiden beschriebenen 'Merkwürdigkeiten' gestolpert.. Ich werde es jetzt 'stressfrei' so machen, dass ich die ermittelten FKs droppe und nach dem Transfer wieder entsprechend created! DAS funktioniert einwandfrei mittels Delphi
      Normalerweise - dh. für den 'echten' Betrieb wird die Datenbank und die zugehörigen Tabellen eh erst frisch angelegt - und da werd ich halt die FKs etc erst nach dem Transfer anlegen...

      Comment

      Working...
      X