Datenbank: MSSQL • Version: 2005 • Zugriff über: ADO
Auto-Insertwert abfragen
Moin,
wie kann ich in diesem Konstrukt den Autoinc-Wert abfragen?
Delphi-Quellcode:
Die Table hat ein Feld mit dem Namen Aktenr, welches AUTOINC ist.
_stmp := 'select * from Akten';
_query := Tadoquery.Create(nil); with _query do begin connection := mus_Service.ADOConnMUS; try _query.sql.Text := _stmp; _query.open; insert; FieldValues['Datum_und_Zeit'] := Datum_und_Zeit; FieldValues['SenderIP'] := SenderIP; FieldValues['eMail'] := eMail; FieldValues['Telefon'] := Telefon; FieldValues['Mobile'] := Mobile; FieldValues['Art'] := Art; post; result := xxx; // Hier die Abfrage finally freeandnil(_query); result := 0; end; end; Gruss EL |
Re: Auto-Insertwert abfragen
Ich habe mal ein bisschen gegockelt und das Einzige, was ich finden konnte ist, sofort nach dem Insert die Identity abzufragen. Beispiel in PHP (von hier):
Code:
$result = mssql_query("INSERT INTO STUFF(gaga,otherGaga) VALUES ('hello','apple'); SELECT @@IDENTITY as insertId;");
|
Re: Auto-Insertwert abfragen
Zitat:
Gruss EL |
Re: Auto-Insertwert abfragen
Nur ne idee, kenn mich mit MSSQL nicht aus, aber:
steht sowas nicht in ner System-tabelle? |
Re: Auto-Insertwert abfragen
Hallo,
mir ist da nur eine Möglichkeit bekannt, ein Select auf genau den Datensatz, den Du soeben eingefügt hast. Ins Unreine ungefähr so:
SQL-Code:
Sofern Du "alleine" auf der Datenbank unterwegs bist, also keiner parallel oder fast parallel Daten einfügen kann, dann könntest Du dank AutoInc auch mit
select AutoIncSpalte from Akten
where Datum_und_Zeit = :Datum_und_Zeit and SenderIP = :SenderIP and eMail = :eMail and Telefon = :Telefon and Mobile = :Mobile and Art = :Art
SQL-Code:
zum Ziel kommen. Fügen mehrere Personen, Programm... Daten ein, so scheitert das, da nicht sichergestellt ist, dass Dein Satz der Neueste ist und damit über diesen Wert verfügt.
select max(AutoInc_Spalte) from Akten
Stephan |
Re: Auto-Insertwert abfragen
Einfach nach dem Post den Wert in einer getrennten Abfrage auslesen.
SQL-Code:
(Scope_Identity() ist besser geeignet weil @@identity den wirklich letzten Auto Wert der aktuellen Session zurückgibt. Führt ein Insert in eine Tabelle einen InsertTrigger aus, der selbst wieder in eine andere Tabelle mit Autoinc Wert was einfügt, so gibt dir @@identity diesen letzten Wert zurück.
select Scope_Identity()
Angst um parallelen Zugriff muss man übrigens nicht haben, weil dieses Ganze Identity Auslesen Session bezogen ist, sich also auf eine Connection bezieht. Persönlich allerdings bevorzuge ich das Reservieren eines eindeutigen Werte bereits vor dem Insert (In anderen Datenbank als Sequenzen bekannt). Hier muss man allerdings darauch achten, dass die Ganze Spielerei transaktionssicher ist (sobald es mehr als eine SQL Anweisung ist kann es passieren, dass eine andere Session dazwischenfunkt). Hier z.B. mal der Code zum Nachahmen von Sequenzen unter MSSQL. Dazu noch eine geeignete Delphi Klasse zum Kapseln, und schon erhält man ganz easy bereits vorm Insert einen eindeutigen ID Wert auch ohne diese Identity Gedöhns (was einem z.B. bei .NET tierisch auf den Sack geht weil connectionslos gearbeitet wird).
SQL-Code:
Man beachte hier in der Stored Procedure das
CREATE TABLE [dbo].[Sequence] (
[SequenceName] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [CurrentValue] [bigint] NOT NULL , [Increment] [int] NOT NULL , [CreationDate] [datetime] NOT NULL ) ON [PRIMARY] GO ALTER TABLE [dbo].[Sequence] WITH NOCHECK ADD CONSTRAINT [PK_Sequence] PRIMARY KEY CLUSTERED ( [SequenceName] ) ON [PRIMARY] GO ALTER TABLE [dbo].[Sequence] ADD CONSTRAINT [DF_Sequence_CurrentValue] DEFAULT (0) FOR [CurrentValue], CONSTRAINT [DF_Sequence_Increment] DEFAULT (1) FOR [Increment], CONSTRAINT [DF_Sequence_CreationDate] DEFAULT (getdate()) FOR [CreationDate], CONSTRAINT [CK_Sequence] CHECK ([Increment] <> 0) GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE PROCEDURE spNextSequence (@SequenceName varchar(255), @SequenceId bigint OUTPUT) AS DECLARE @Increment int SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRANSACTION SP_GEN_ID SET @SequenceId = (Select CurrentValue from Sequence where SequenceName = @SequenceName) IF @SequenceId is null BEGIN insert into Sequence (SequenceName) values (@SequenceName) SET @SequenceId = (Select CurrentValue from Sequence where SequenceName = @SequenceName) END SET @Increment = (Select Increment from Sequence where SequenceName = @SequenceName) update Sequence set CurrentValue=CurrentValue+@Increment where SequenceName = @SequenceName SET @SequenceId = (Select CurrentValue from Sequence where SequenceName = @SequenceName) COMMIT TRANSACTION SP_GEN_ID GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
SQL-Code:
Damit wird sichergestellt, dass immer nur einer diese Prozedur gleichzeitig ausführen kann.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
|
Re: Auto-Insertwert abfragen
Zitat:
Blöde Frage: Wie baue ich diesen: select Scope_Identity() in dieses Konstrukt ein?
Delphi-Quellcode:
with _query do begin
connection := mus_Service.ADOConnMUS; try sql.Text := _stmp; open; insert; FieldValues['Datum_und_Zeit'] := Datum_und_Zeit; FieldValues['SenderIP'] := SenderIP; FieldValues['eMail'] := eMail; FieldValues['Telefon'] := Telefon; FieldValues['Mobile'] := Mobile; FieldValues['Art'] := Art; post; result := ????? <======== HIER _query.Close; finally freeandnil(_query); result := 0; end; end; Gruss EL |
Re: Auto-Insertwert abfragen
Delphi-Quellcode:
with _query do begin
connection := mus_Service.ADOConnMUS; try sql.Text := _stmp; open; insert; FieldValues['Datum_und_Zeit'] := Datum_und_Zeit; FieldValues['SenderIP'] := SenderIP; FieldValues['eMail'] := eMail; FieldValues['Telefon'] := Telefon; FieldValues['Mobile'] := Mobile; FieldValues['Art'] := Art; post; result := LastIdentity; _query.Close; finally freeandnil(_query); //result := 0; --> Sonst wird dir nach aussen immer 0 ausgegeben end; end; function LastIdentity : integer; begin with _query do begin connection := mus_Service.ADOConnMUS; try sql.Text := 'Select Scope_Identity() as id'; open; if not(FielByName('id').IsNull) then result := FieldByName('id').asInteger; else result := 0; _query.Close; exit; finally freeandnil(_query); end; end; end ; |
Re: Auto-Insertwert abfragen
Zitat:
der liefert mir immer 0 als result :? Gruss EL |
Re: Auto-Insertwert abfragen
Und wenn Du in der Funktion eine eigene lokale Query erzeugst?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz