2009-05-01 6 views
2

Ich habe ein dreistufiges System, SQL Server-Backend, handgeschriebene Datenzugriffsschicht und gespeicherte Prozeduren verwenden.Muss ich nach dem Erstellen einer neuen Zeile in der Datenbank den Primärschlüssel an die Zeile oder ein Datenübertragungsobjekt zurückgeben?

Ich habe eine Tabelle namens EventTable. Jede Zeile ist ein 'Event'. Ein Ereignis hat einen Primärschlüssel und ein Startdatum.

CREATE TABLE EventTable 
(
    ID INT IDENTITY(100,1) PRIMARY KEY, 
    StartTime DateTime NOT NULL 
) 

Es gibt eine gespeicherte Prozedur namens EventTable_Create. Übrigens, ist die create Methode in Ordnung wie geschrieben?

CREATE PROCEDURE Event_Create 
    @NewID INT OUT 
AS 
    DECLARE @START DATETIME 
    SELECT @START = getdate() 
    INSERT INTO EventTable VALUES(@START, NULL) 
    SELECT @NewID = MAX(ID) FROM EventTable 
GO 

Die Datenzugriffsebene gibt ein int an den Aufrufer zurück, sollte sie stattdessen eine Instanz eines Datenübertragungsobjekts namens Event zurückgeben? Wenn das wahr ist, sollte ich sowohl die neu erstellte ID als auch die Startzeit zurückgeben, damit die Datenzugriffsebene das Ereignisübertragungsobjekt erstellen kann?

+1

Uh, das ist die gespeicherte Prozedur für "Experiment", nicht "Event". – Portman

Antwort

3

Es hängt alles davon ab, was Sie in Ihrer Domain-Schicht über den Datenzugriff benötigen. Da Sie dies durch Übergeben der Informationen von der Domänenebene erstellen, nehme ich an, dass Sie die meisten Ereignisinformationen bereits in Ihrer Domänenlogik haben. In diesem Fall benötigen Sie lediglich eine ID, um sie als Teil Ihres Ereignisobjekts zu füllen, falls Sie eines haben.

Es hängt also alles davon ab, was Sie in Ihrer Domainebene benötigen und aus welchen Gründen.

2

Soweit was Sie benötigen, um zurückzukehren, würde jeder Weg wahrscheinlich funktionieren. Wie CodeToGlory sagte, kommt es darauf an. Ich würde mich darauf konzentrieren, beide Werte selbst zurückzugeben.

Ich würde ändern, wie ich die Identitätsspalte in der gespeicherten Prozedur abrufen. Es gibt ein paar Möglichkeiten, um es zu bekommen.

Statt: SELECT @NewID = MAX (ID) FROM EXPERIMENTTABLE

ich tun würde: Set @NewID = @@ Identität

oder

Set @NewID = SCOPE_IDENTITY()

Hier ist ein Auszug aus Büchern online mit einem Beispiel. Ich kann Ihnen helfen zu entscheiden, welche zu verwenden:

Zum Beispiel gibt es zwei Tabellen, T1 und T2, und ein INSERT-Trigger ist auf T1 definiert. Wenn eine Zeile in T1 eingefügt wird, wird der Trigger ausgelöst und eine Zeile in T2 eingefügt. In diesem Szenario werden zwei Bereiche veranschaulicht: der Einschub in T1 und der Einschub in T2 durch den Auslöser.

Unter der Annahme, dass sowohl T1 als auch T2 Identitätsspalten haben, geben @@ IDENTITY und SCOPE_IDENTITY unterschiedliche Werte am Ende einer INSERT-Anweisung in T1 zurück. @@ IDENTITY gibt den letzten Wert der Identitätsspalte zurück, der über einen Bereich in der aktuellen Sitzung eingefügt wurde. Dies ist der in T2 eingefügte Wert. SCOPE_IDENTITY() gibt den in T1 eingefügten IDENTITY-Wert zurück. Dies war die letzte Einfügung im selben Bereich. Die Funktion SCOPE_IDENTITY() gibt den Nullwert zurück, wenn die Funktion aufgerufen wird, bevor INSERT-Anweisungen in einer Identitätsspalte im Gültigkeitsbereich auftreten.

0

Sie sollten MAX (ID) nicht verwenden, um den Primärschlüssel des neu hinzugefügten Datensatzes abzurufen.

Verwenden Sie stattdessen Identität.

INSERT INTO tbl(...) VALUES(...); 

SELECT @@Identity as NewID; 
+0

Oder SCOPE_IDENTITY() wie Sean sagte. –

1

Sie sollten den einzigen Primärschlüssel zurückgeben, wenn Sie nicht die gesamte Datenstruktur benötigen. Das Zurücksetzen der gesamten Datenstruktur ohne einen bestimmten Grund ist verschwenderisch.

+0

Dies gilt nicht als eine undichte Abstraktion? – MedicineMan

+0

Nicht sicher, dass ich folge. Meinst du, dass wir bei der Rückgabe des Schlüssels davon ausgehen, dass alles andere wie erwartet eingefügt wurde, während wir durch die Rückgabe der gesamten Datenstruktur sicher sein können? –

+0

OK, ich habe ein wenig mehr über das Thema gelesen (noch nie davon gehört, also danke für die Erleuchtung). Aus der Perspektive von Ihnen als Person erscheint es nicht als eine undichte Abstraktion: Sie haben Ihre eigene Datenschicht geschrieben und Procs gespeichert, also ist der Umgang mit einem Primärschlüssel nicht weniger abstrakt als alles andere. Aus der Perspektive der mittleren Ebene selbst könnte es als eine undichte Abstraktion betrachtet werden, je nachdem, wie Sie darüber denken. Wenn Sie den Primärschlüssel einfach als ein Token betrachten, das Ihre mittlere Schicht verwenden kann, um den Rest der Daten zu erhalten, verlieren Sie meiner Meinung nach nicht wirklich Abstraktion. –

Verwandte Themen