1

Temat: Wykrycie referencji

Witam
Mam problem z wykryciem referencji z tabeli A do tabeli B. Już tłumaczę:
Powiedzmy, że chcę usuną wartość "a" z tabeli A i chcę sprawdzić czy ta warotść jest używana w tabeli B.

W moim programie używam adoconnection (dynamicznie budowane) i w zapytaniu do bazy nie zwraca mi żadnych wyników błędnych lub niemożliwych do wykonania, stąd właśnie moje pytanie. Być może istnieje zapytanie, które zwróci mi komunikat, że taka wartość "a" jest użyta w tabeli B.

2

Odp: Wykrycie referencji

Ostatnio edytowany przez Rady (2008-02-07 22:14:25)

3

Odp: Wykrycie referencji

Ok Tabela pierwsza
  TabelaJednostekMiar = '(id bigserial not null, '+
                                  'nazwa_jednostki varchar(64) not null, '+
                                  'PRIMARY KEY(id), UNIQUE (nazwa_jednostki));';

  TabelaTypowTowarow = '(id bigserial not null, '+
                       'nazwa_typu text null, '+
                       'PRIMARY KEY(id), UNIQUE (nazwa_typu));';

  TabelaTowarow = '(id bigserial not null, '+
                  'flag boolean not null, '+
                  'nazwa varchar(128) not null, '+
                  'nazwa_fiskalna varchar(16) null, '+
                  'nr_fvz varchar(32) not null, '+
                  'id_jm integer not null, '+
                  'id_typ text not null, '+
                  'ilosc float not null, '+
                  'cena float null, '+
                  'marza float not null, '+
                  'sn varchar(128) null, '+
                  'created_by integer null, '+
                  'modified_by integer null, '+
                  'created_date date null, '+    // 1999-01-08
                  'modified_date date null, '+   // 1999-01-08
                  'PRIMARY KEY(id), '+
                  'CONSTRAINT id_jm FOREIGN KEY (id_jm) REFERENCES kartoteki.jednostki_miar (id) ON UPDATE NO ACTION ON DELETE NO ACTION, '+
                  'CONSTRAINT id_typ FOREIGN KEY (id_typ) REFERENCES kartoteki.typ_towarow (nazwa_typu) ON UPDATE NO ACTION ON DELETE NO ACTION);';

i teraz tworze zapytania budujace baze

    SQL_CommandRun(DB_AdoCommand, '', PChar('CREATE TABLE kartoteki.jednostki_miar' +TabelaJednostekMiar));
    SQL_CommandRun(DB_AdoCommand, '', PChar('CREATE TABLE kartoteki.table_typ_towarow' +TabelaTypowTowarow));
    SQL_CommandRun(DB_AdoCommand, '', PChar('CREATE TABLE kartoteki.table_towary' +TabelaTowarow));

dalej funkcja SQL_CommandRun:

function SQL_CommandRun(DB_AdoCommand : TADOCommand; baza, zapytanie : String) : Boolean;
begin
  try
    if baza <> '' then
    begin
      SetDB_box.DB_Connect := DB_Connect;
      SetDB_box.plik := path_dir +dir_prefs +'\' +file_prefs;
      SetDB_box.plik_pack := path_dir +LibPack;
    end;
    SQL_Command(DB_AdoCommand, baza, zapytanie, SetDB_box);
  except; end;
end;

i dalej zapytanie umieszczone w bibliotece DLL:

procedure SQL_Command(DB_AdoCommand : TADOCommand; baza, zapytanie : String; SetDB_box : TSetDB); external LibConnect;

a oto i sama biblioteka:

procedureSQL_Command(DB_AdoCommand : TADOCommand; baza, zapytanie : String; SetDB_box : TSetDB);
begin
  if baza <> '' then SetDB(SetDB_box.DB_Connect, SetDB_box.plik, SetDB_box.plik_pack, baza);  // aktywuje baze
  DB_AdoCommand.CommandType := cmdText;
  DB_AdoCommand.CommandText := zapytanie;
  try
    DB_AdoCommand.Execute;
  except
  end;
end;


Trochę to pogmatfane ale działa dobrze. Użyłem try except na wypadek wszelkich blędów powodujących wywołaniami bezpośrednio z biblioteki.
mój problem rozwiązałem robiac w ten sposób:

begin
  SQL_CommandRun(DB_AdoCommand, db_rksystem +InfoDB.rok, 'DELETE FROM kartoteki.jednostki_miar' WHERE id='''+IntToStr(id)+''';');
  if SprawdzMozliwoscZapisu('kartoteki', 'jednostki_miar', 'id='''+IntToStr(id)+'''') > 0 then
  begin
    Komunikat('Jednostka miary jest przypisana do towaru, i nie ma możliwości usunięcia jej.');
    Exit;
  end;
end;

4

Odp: Wykrycie referencji

Widze że miałeś zdefiniowane zależności w tabeli to na "Try'ach" dało by sie złapać błąd podczas usuwania, ale pomysł z if i message też niezły. Wiesz jak bawiłem się na Delphi to łapałem właśnie komunikat błędu z serwera podczas próby usunięcia wartości klucza obcego bez usuwania bez usuwania jego poprzednika PK.

Tylko używałem jeszcze przy tworzeniu FK "on update cascade"


Daj sobie jeszcze obsługę transakcji dla Update i Insert to będziesz miał pewniachę że baza Ci się nie rozjedzie przy kilku klientach działających jednocześnie.

Ostatnio edytowany przez Rady (2008-02-08 00:05:22)

5

Odp: Wykrycie referencji

6

Odp: Wykrycie referencji

W jakimś stopniu na pewno wydłuży czas oczekiwania na modyfikacje ale bazy Ci się nie rozjadą, czas wykonania transakcji jest praktycznie znikomy z tego co zauważyłem na Postgresie żeby klient zobaczył jakąkolwiek różnicę musiało by z 10 osób modyfikować tą samą daną w tym samym momencie, a i tak wydaje mi się że stabilność bardziej się liczy. Na lokalnych bazach można to ominąć ale na sieciowych ja bym nie ryzykował.

Ostatnio edytowany przez Rady (2008-02-08 17:57:06)

7

Odp: Wykrycie referencji

Ok przekonałeś mnie. W sumie używałem transakcji wtedy kiedy uważałem że wszystkie operacje powinny zostać wykonane.
W zasadzie nie myślałem o tym aby dla jednej operacji INSERT lub UPDATE używać transakcji.

8

Odp: Wykrycie referencji

Mam pytanko jaki typ danych z Postgresa będzie najbardziej odpowiedni dla danych Delphi typu memo ??

9

Odp: Wykrycie referencji

Ostatnio edytowany przez rafko (2008-02-11 12:37:16)