nochwas:
select @Nummer = max (Nummer) from Nummern where Datum is null
So würde ich das machen.
Nun zu Deiner Frage:
select top 1 Nummer from Nummern where Datum is null order by nummer desc
scheint etwas (aber wirklich nur etwas) besser zu sein, als
select max (Nummer) from Nummern where Datum is null
aber nur unter der Voraussetzung, das Nummern und Datum indiziert ist. Ohne das näher zu analysieren würde ich annehmen, das der clustered Index auf dem 'Datum' liegen muss, damit die beiden Versionen identisch sind.
Ansonsten ist Variante 1 (also MAX) eindeutig besser, ohne Index ca. 10x schneller. Mit einfachen Indizes ca 3x. Ich denke, das liegt am Sortieren. Ich hab das rudimentär mit einer 100.000 Tabelle getestet, da tut das Sortieren natürlich weh. ORDER BY wird nur bei clustered indexen ignoriert, denn da liegen die Daten schon richtig sortiert vor.
Unabhängig davon ist es blasphemisch, die nächste Rechnungsnummer so zu erzeugen (finde ich). Denn der Server wird überflüssigerweise mit Arbeit zugeballert (außer, die Indexe stimmen). Stell Dir einfach vor, es wären 100.000.000 Rechnungen (na ja, wer hat die schon, aber egal).
Ich arbeite gerade am gleichen Problem und verwende einen Zähler. Ich habe eine Tabelle mit Rechnungen, die nun fakturiert werden sollen. Ich erzeuge eine temporäre Tabelle über dynamisches
SQL, und zwar mit zwei Spalten ('IDRechnung' und 'RechnungsNr'). Die RechnungsNr wird als Identity deklariert, der Seed wird auf die nächste freie Rechnungsnummer gesetzt. Das geht mit plain
SQL nicht, also erzeuge ich mir das folgende Statement als String und führe es einfach mit EXEC aus:
SQL-Code:
CREATE TABLE #Foo (
IDRechnung int, 'ü
RechnungsNr int identity (12345,1)
)
Die Tabelle erzeugt also automatisch neue Rechnungsnummern, sobald die Tabelle gefüllt wird, und zwar so:
SQL-Code:
insert into #Foo (IDRechnung)
select IDRechnung from Rechnungen where Status='Offen'
Damit habe ich optimal schnell und garantiert fortlaufend alle Rechnungsnummern erzeugt. Danach kopiere ich die Rechungsnummern in die Rechnungstabelle zurück:
SQL-Code:
Update Rechnungen
set RechnungsNr = #Foo.RechnungsNr
From #Foo
Where Rechungen.RechungsNr = #Foo.RechungsNr
Zum Schluss nur noch die neue maximal Rechnungsnummer in meine Zählertabelle eintragen und fertig.
Update Counters Set Counter = (select max (RechnungsNr)+1 from #Foo) where cntID = 2