Firebird Insert Helyesen

Firebird Insert Helyesen
2013-09-30T16:27:22+02:00
2014-02-03T14:02:12+01:00
2022-11-30T11:50:33+01:00
Levi1976
Sziasztok !
Kezdő delphi firebird programozó vagyok.
Rengeteget olvasgattam a neten hogy hogy kellene helyesen beszúrni egy új rekordot egy Firebird táblába tárolt eljárással főleg úgy hogy a hibákat is lekezelje.
De nem igazan kaptam kielégítő választ.

Tábla
ID INTEGER NOT NULL, UNIQUE, PRIMARY KEY
NEV VARCHAR(50) NOT NULL, UNIQUE
OSSZEG NUMERIC(9,2) NOT NULL

Tárolt eljárás

-- Procedure: INSERT1

-- DROP PROCEDURE INSERT1;

SET TERM ^ ;

RECREATE PROCEDURE INSERT1 (
NEV VARCHAR(50),
ID INTEGER,
OSSZEG NUMERIC(9,2)
RETURNS (
ELLENORZES SMALLINT)
AS
DECLARE VARIABLE EXISTS1 SMALLINT;
BEGIN
ELLENORZES=0;
EXISTS1=0;


SELECT FIRST 1 ID
FROM TABLA
WHERE NEV=:NEV AND ID=:ID
INTO :EXISTS1;

IF (:EXISTS1=0) THEN
BEGIN
INSERT INTO TABLA
(
NEV,
ID,
OSSZEG
)
VALUES (
:NEV,
:ID,
:OSSZEG
);
END

ELSE ELLENORZES=1;
SUSPEND;
END^

SET TERM ; ^


Delphi IBStoredProcedure

with UDM.DM.SP_Insert1 do
begin
try
ParamByName('nev').AsString:=Edit1.Text;
ParamByName('osszeg').AsFloat:=StrToFloat(Edit2.Text);
ParamByName('ID').AsInteger:=UDM.DM.tabla_DatasetID.Value;
Prepare;
ExecProc;
if ParamByName('ELLENORZES').AsSmallInt=1 then
begin
Beep;
Application.MessageBox('Mar Letezzik !!!','Elso',MB_OK+MB_ICONEXCLAMATION);
Edit1.SetFocus;
Exit;
end;

finally
if ParamByName('ELLENORZES').AsSmallInt=0 then
begin
Beep;
UDM.DM.tabla_DataSet.Close;
UDM.DM.tabla_DataSet.Open;
UDM.DM.tabla_DataSet.Last;
Application.MessageBox('Elmentve !!!','',MB_OK+MB_ICONINFORMATION);

end;

end;
end;

A try, exception és finally hogy kell helyesen használni?
Minden ötletre nyitott vagyok mert ez csak az Insert meg hátra van a Delete és az Update is.
Az adatok frissitésére megfelel az Open és Close vagy Active := False és Active := True használjak?

Köszönöm Szépen
Mutasd a teljes hozzászólást!

  • Használd a forráskód gombot a hozzászólásnál!
    Mutasd a teljes hozzászólást!
  • Ok
    Bocs de ez az első témám az oldalon.
    De ezután úgy csinálom.
    Elnézést meg egyszer.
    Mutasd a teljes hozzászólást!
  • Hali!

    Bocs de ez az első témám az oldalon.


    Nem az első, ráadásul a másik nickeddel sem nagyon használtad a forráskód-gombot (egyáltalán: mi szükség másod-nickre?).

    Mutasd a teljes hozzászólást!
  • Szia!

    Alapvetően jó az elgondolásod!

    Én így csinálom:

    SET TERM ^ ; create or alter procedure CIKKTORZS_INSERT ( X_NEV varchar(80), X_KSH varchar(15), X_AFAKULCS double precision, X_MENNY_EGYS varchar(7), X_EGYSEGAR double precision, X_MEGJEGYZES blob sub_type 1 segment size 4096, X_AFAKULCSID integer, X_ARBEVETEL varchar(15), X_EGYSEG_ID integer) returns ( HIBA integer, NEW_ID integer) as begin begin HIBA=0; if (x_nev = '') then x_nev = null; if (x_ksh = '') then x_ksh = null; if (x_menny_egys = '') then x_menny_egys = null; if (x_arbevetel = '') then x_arbevetel = null; insert into cikktorzs (nev, ksh, afakulcs, menny_egys, egysegar, megjegyzes, afakulcs_id, fok_arbevetel, egyseg_id) values (:x_nev, :x_ksh, :x_afakulcs, :x_menny_egys, :x_egysegar, :x_megjegyzes, :x_afakulcsid, :x_arbevetel, :x_egyseg_id) returning id into :new_id; when any do HIBA=sqlcode; end suspend; end^ SET TERM ; ^ /* Following GRANT statetements are generated automatically */ GRANT INSERT ON CIKKTORZS TO PROCEDURE CIKKTORZS_INSERT; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE CIKKTORZS_INSERT TO SYSDBA;
    sqlcode helyett használhatod a gdscode-t is, a konkrét értékeket megtalálod a "FireBird error codes"-ban!

    Delphi oldalon pedig:

    DM.spAruInsert.Close; DM.spAruInsert.Prepare; DM.spAruInsert.ParamByName('X_NEV').AsString := Trim(eNev.Text); DM.spAruInsert.ParamByName('X_KSH').AsString := Trim(eKSH.Text); DM.spAruInsert.ParamByName('X_AFAKULCS').AsFloat := QryAFAKULCS.Value; DM.spAruInsert.ParamByName('X_MENNY_EGYS').AsString := QryEgysegROVID_NEV.AsString; DM.spAruInsert.ParamByName('X_EGYSEGAR').AsFloat := eEAR.Value; DM.spAruInsert.ParamByName('X_FOK_ARBEVETEL').AsString := Trim(eArbevetel.Text); DM.spAruInsert.ParamByName('X_MEGJEGYZES').AsString := mComment.Text; DM.spAruInsert.ParamByName('X_AFAKULCSID').AsInteger := QryAFAID.AsInteger; DM.spAruInsert.ParamByName('X_REZSI').AsInteger := IfThen(cBoxRezsi.Checked, 1, 0); DM.spAruInsert.ExecProc; i := DM.spAruInsert.ParamByName('HIBA').AsInteger; if i = 0 then begin aruID := DM.spAruInsert.ParamByName('NEW_ID').AsInteger; if DM.TrAruk.Active then if DM.TrAruk.InTransaction then DM.TrAruk.Commit; end else begin if DM.TrAruk.Active then if DM.TrAruk.InTransaction then DM.TrAruk.Rollback; end;
    Ami fontos, az, hogy a stored proc saját tranzakciót kap!
    (Nem az adatbázis "tranzakcióját" használja!)
    P.S.
    Utólag nézve jól bekavartam a tárolt eljárás / Delphi kódot...
    (Más adatbázisból vettem a példát, mint a amit a Delphis kód használ! BOCS!)
    De remélem a lényeget érteni fogod!
    Mutasd a teljes hozzászólást!
  • Szia !

     Próbáltam kibogarászni a kódodat, és volna pár építő jellegű meglátásom:
    1. Nem szokás azonos neveket használni a paramétereknek, mint amit a tábla-mezőknél már használsz (ID = :ID) ...

    Elvileg nem akad ki, de azért ez okozhat problémákat / tévesztéseket (főleg júzer szemszögből)

    Tehát pl.:

    RECREATE PROCEDURE INSERT1 ( NEV_BE VARCHAR(50), ID_BE INTEGER, OSSZEG_BE NUMERIC(9,2) RETURNS (ELLENORZES_KI SMALLINT) ...

    értelmezhetőbbé tenné az összehasonlításokat, stb.

    2. Én ELŐBB mindig Active := True -val kezdek, és után az .open illetve .Execquery
    Ez vált be, mert ha véletlenül az "Auto" False-ra van állítva, akkor kiakad.

    3. Erős túlzásnak érzem a kódodat, hiszen ELEVE unique -ra van definiálva mind az ID, mind a NEV, tehát NEM fog engedni amúgy sem beszúrni olyat, ami már létezik !

    Ergo Bőven elég a Try ... Except a Delphi oldalon és kész.

    try s := 'insert into TABLA (ID, NEV, OSSZEG) VALUES (546,'Kis János', 4.5889 )' Except Showmessage('Hiba történt a beszúráskor'); end;

    4. külön-külön Unique-ra van definiálva az ID és a NEV is !
    Tehát vagy ezt kellene
    WHERE NEV=:NEV AND ID=:ID
     helyett
    WHERE NEV=:NEV OR ID=:ID

    Vagy a NEV mező unique index-ét törölnöd kellene, mert így nem fog engedni 2 azonos "Kis János" nevű embert felvinni!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd