ID ostatnio dodanego rekordu z bazy MSSQL.

ID ostatnio dodanego rekordu z bazy MSSQL.
GR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 3 lata
0

Witam,
Wprowadzam do bazy danych jakieś dane poprzez INSERT i chcę po wprowadzeniu tych danych otrzymać ich ID utworzone automatycznie przez serwer MSSQL.
Wiem jak to zrobić w samym SQL ale nie wiem jak wydobyć to ID za pomocą Delphi. Jak mam w Delphi wyświetlić dane zwracane przez scope_identity() idx
Mój kod:

Kopiuj
if data1.MSSQL1.Connected then
        SQLQuery1.Close;
        SQLQuery1.SQL.Clear;
        SQLQuery1.SQL.Add('INSERT  INTO dbo.t_tw (nr_kodowy, nazwa, il_w_partii, nr_dok_prze, nr_partii, data_dos)VALUES('''+ EditSzukajRAC.Text + ''','''+EditRACName.Text+''','''+EditRACIloscPartii.Text+''','''+EditRACNrDokPrzew.Text+''','''+EditRACNrPartii.Text+''','''+EditRACDataDostawy.Text+'''); SELECT scope_identity() idx');

    try
        SQLQuery1.ExecSQL;
        showmessage(''+SQLQuery1.FieldByName('idx').AsString+'');
    except
        ShowMessage('Wystąpił błąd podczas wstawienia rekordu Form4');
    end;
    SQLQuery1.Active := False;
 

Już siedzę nad tym trzy dni i głowami pęka, proszę o wskazówkę co zrobić. Dziękuję.

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 20 godzin
  • Postów:3881
0

Nie jestem specem od delphi ale dodaj na początku zapytania:

Kopiuj
Set nocount on;

Dodatkowo execsql nie zwraca danych, to do weryfikacji od tych co się znają. Ale chyba trzeba zmienić na open...

edytowany 1x, ostatnio: flowCRANE
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:2 minuty
0

@Panczo: , a ja nie jestem specem od MSSQL :) ale insert czy update jako podstawowa komenda w zapytaniu realizowanym za pomocą bazodanowych komponentów Delphi wymaga execsql
open to przy select.
a autor chyba mocno zamieszał budując zapytanie

edytowany 1x, ostatnio: flowCRANE
0

Jaki masz komunikat błędu? A może nie masz błędu tylko ID nie pokazuje? Doprecyzuj.

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:2 minuty
1

obsługa wyjątku zastosowana przez autora maskuje pierwotny wyjątek
zamiast tego

Kopiuj
 except
        ShowMessage('Wystąpił błąd podczas wstawienia rekordu Form4');
 end;

lepiej tak to zrobić

Kopiuj
except
    on e:exception do 
         ShowMessage('Wystąpił błąd podczas wstawienia rekordu Form4 ' +#13+#10+e.message);
end
edytowany 3x, ostatnio: flowCRANE
LA
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 3 godziny
  • Postów:471
4

Spróbuj tak:

Kopiuj
'INSERT INTO tabela (wartosci....) ' +
'OUTPUT INSERTED.nazwa_pola_z_ID ' +  //zwraca wstawione ID
'VALUES ' +
'( wartosci......)';
Kopiuj
Query.OpenOrExecute;

if Query.RecordCount = 1 then
  Result := Query.FieldByName('nazwa_pola_z_ID').AsInteger;

i zacznij używać parametryzowanych zapytań oraz kłania się obsługa wyjątków.

GS
"i zacznij używać parametryzowanych zapytań oraz kłania się obsługa wyjątków." !!!!
PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 20 godzin
  • Postów:3881
0
grzegorz_so napisał(a):

@Panczo: , a ja nie jestem specem od MSSQL :) ale 'insert' czy 'update' jako podstawowa komenda w zapytaniu realizowanym za pomocą bazodanowych komponentów Delphi wymaga 'execsql'
'open' to przy 'select'.
a autor chyba mocno zamieszał budując zapytanie

Nie wiem, czy zamieszał, ale tam ostatni jest select, jako, że na Delphi znam się jak kot na gwiazdach to zrobiłem research i tu potwierdza się różnica między execsql, a open: http://stackoverflow.com/questions/33280954/get-last-row-data-after-insert-into-using-delphi-adoquery

Ale upierać się nie będe ;)

Ale to też ciekawe, że minuta z google daje dokładnie odpowiedź na pytanie, a OP piszę, że męczy się z tym 3 dni...

edytowany 1x, ostatnio: Panczo
GR
  • Rejestracja:około 18 lat
  • Ostatnio:ponad 3 lata
0

Dziękuję Panowie,
Dziękuję wszystkim za zainteresowanie i pomoc, Lampasss dziękuję za podpowiedź, działa - tak przy okazji dopiero uczę się SQL i odkrywam możliwości Delphi. Grzegorz_so dziękuję za podpowiedź odnośnie wyświetlenia wyjątków.

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:2 minuty
0

@Panczo: , w delphi i bazodanowych 'datasetach' reguły są proste , jeśli odczyt danych z bazy to zawsze 'open', a w każdym innym przypadku "execsql"

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 20 godzin
  • Postów:3881
0

@grzegorz_so: jak, pokazał @lampasss jest jeszcze 3 droga: Query.OpenOrExecute :)

GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:2 minuty
0

może i masz rację:) Zależy od tego jakie komponenty bazodanowe są w użyciu . Te z których ja do tej pory korzystałem przy odczycie zawsze wymagały użycia 'open' , a w każdej innej sytuacji 'execsql'

edytowany 1x, ostatnio: grzegorz_so
GS
  • Rejestracja:ponad 14 lat
  • Ostatnio:2 minuty
0

@Panczo : z tego co znalazłem w necie, to metodę OpenOrExecute implementują komponenty FireDac będące częścią środowiska Delphi od wersji XE5

PA
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 20 godzin
  • Postów:3881
0

@grzegorz_so: ok, ja nie piszę w Delphi, a OP nie zdefiniował z jakich komponentów korzysta, założyłem tylko, że skoro przekazuje w zapytaniu kilka instrukcji to istotne jest czy ona coś zwraca. Dlatego zwróciłem uwagę, na Open, a nie ExecSQL.

GS
jasne :))) i myślę że nie warto o to toczyć boje :))) pozdrawiam serdecznie i świątecznie :) G.S.
PA
Nawet nie zamierzałe toczyć bojów, bo Delphi nie znam... Również pozdrawiam i wesołych świąt życzę
woolfik
  • Rejestracja:ponad 17 lat
  • Ostatnio:25 minut
  • Postów:1599
3

Panowie ja tylko tak w gwoli ścisłości. Jeśli pytacz używa FireDAC, to bez względu czy odpali procedurę bazodanową, która robi insert, czy wali inserta z kodu zwykłym poleceniem insert i bez względu na Open/ExecSQL/ExecProc to komponent TADCOnnection/TFDConnection w zależności od wersji delphi ma możliwość zwrócenia ostatniej wartości sekwencji po jej podaniu ;)
http://docwiki.embarcadero.com/Libraries/XE8/en/FireDAC.Comp.Client.TFDCustomConnection.GetLastAutoGenValue

0

można też tak z podaniem z której tabeli wyciągamy ID

Kopiuj
 format('SELECT ident_current(''%s'') AS IdNewDok', [nazwa_tabeli]);

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.