Was entspricht der RowID von Oracle in SQL Server?
sql
sql-server
tsql
rowid
row-number
John Saunders
quelle
quelle
Antworten:
Aus den Oracle-Dokumenten
Das nächste Äquivalent dazu in SQL Server ist
rid
das mit drei KomponentenFile:Page:Slot
.In SQL Server 2008 ist es möglich, die undokumentierte und nicht unterstützte
%%physloc%%
virtuelle Spalte zu verwenden, um dies anzuzeigen . Dies gibt einenbinary(8)
Wert mit der Seiten-ID in den ersten vier Bytes zurück, dann 2 Bytes für die Datei-ID, gefolgt von 2 Bytes für die Position des Steckplatzes auf der Seite.Die Skalarfunktion
sys.fn_PhysLocFormatter
oder diesys.fn_PhysLocCracker
TVF können verwendet werden, um dies in eine besser lesbare Form umzuwandelnCREATE TABLE T(X INT); INSERT INTO T VALUES(1),(2) SELECT %%physloc%% AS [%%physloc%%], sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot] FROM T
Beispielausgabe
+--------------------+----------------+ | %%physloc%% | File:Page:Slot | +--------------------+----------------+ | 0x2926020001000000 | (1:140841:0) | | 0x2926020001000100 | (1:140841:1) | +--------------------+----------------+
Beachten Sie, dass dies vom Abfrageprozessor nicht genutzt wird. Es ist zwar möglich , dies in einer
WHERE
Klausel zu verwendenSELECT * FROM T WHERE %%physloc%% = 0x2926020001000100
SQL Server sucht nicht direkt nach der angegebenen Zeile. Stattdessen wird ein vollständiger Tabellenscan durchgeführt,
%%physloc%%
für jede Zeile ausgewertet und die übereinstimmende zurückgegeben (falls vorhanden).Um den von den beiden zuvor genannten Funktionen ausgeführten Vorgang umzukehren und den
binary(8)
Wert zu erhalten, der den bekannten Werten für Datei, Seite und Steckplatz entspricht, können die folgenden Werte verwendet werden.DECLARE @FileId int = 1, @PageId int = 338, @Slot int = 3 SELECT CAST(REVERSE(CAST(@PageId AS BINARY(4))) AS BINARY(4)) + CAST(REVERSE(CAST(@FileId AS BINARY(2))) AS BINARY(2)) + CAST(REVERSE(CAST(@Slot AS BINARY(2))) AS BINARY(2))
quelle
Ich muss einen sehr großen Tisch mit vielen Spalten deduplizieren und Geschwindigkeit ist wichtig. Daher verwende ich diese Methode, die für jede Tabelle funktioniert:
delete T from (select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T Where T.RowNumber > 1
quelle
Überprüfen Sie die neue Funktion ROW_NUMBER . Es funktioniert so:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
quelle
Wenn Sie eine Zeile in der Tabelle und nicht Ihre Ergebnismenge eindeutig identifizieren möchten, müssen Sie die Verwendung einer IDENTITY-Spalte in Betracht ziehen. Siehe "IDENTITY-Eigenschaft" in der SQL Server-Hilfe. SQL Server generiert nicht wie Oracle automatisch eine ID für jede Zeile in der Tabelle. Sie müssen sich also die Mühe machen, eine eigene ID-Spalte zu erstellen und diese explizit in Ihrer Abfrage abzurufen.
BEARBEITEN: Für die dynamische Nummerierung von Ergebnismengenzeilen siehe unten, aber das wäre wahrscheinlich ein Äquivalent für Oracle ROWNUM, und ich gehe von allen Kommentaren auf der Seite davon aus, dass Sie das obige Material möchten. Für SQL Server 2005 und höher können Sie die neue Funktion "Ranking-Funktionen" verwenden, um eine dynamische Nummerierung von Zeilen zu erreichen.
Zum Beispiel mache ich das bei einer Abfrage von mir:
select row_number() over (order by rn_execution_date asc) as 'Row Number', rn_execution_date as 'Execution Date', count(*) as 'Count' from td.run where rn_execution_date >= '2009-05-19' group by rn_execution_date order by rn_execution_date asc
Werde dir geben:
Row Number Execution Date Count ---------- ----------------- ----- 1 2009-05-19 00:00:00.000 280 2 2009-05-20 00:00:00.000 269 3 2009-05-21 00:00:00.000 279
Es gibt auch einen Artikel auf support.microsoft.com über die dynamische Nummerierung von Zeilen.
quelle
Einige der oben genannten Antworten arbeiten um das Fehlen einer direkten Bezug zu einer bestimmten Zeile, aber wird nicht funktionieren , wenn Änderungen auftreten , zu den anderen Zeilen in einer Tabelle. Das sind meine Kriterien, für die die Antworten technisch unzureichend sind.
Eine häufige Verwendung der ROWID von Oracle besteht darin, eine (etwas) stabile Methode zum Auswählen von Zeilen und zum späteren Zurückkehren in die Zeile bereitzustellen, um sie zu verarbeiten (z. B. um sie zu aktualisieren). Die Methode zum Suchen einer Zeile (komplexe Verknüpfungen, Volltextsuche oder zeilenweises Durchsuchen und Anwenden von Prozedurtests auf die Daten) kann möglicherweise nicht einfach oder sicher wiederverwendet werden, um die UPDATE-Anweisung zu qualifizieren.
Die SQL Server-RID scheint dieselbe Funktionalität zu bieten, bietet jedoch nicht dieselbe Leistung. Dies ist das einzige Problem, das ich sehe, und leider besteht der Zweck der Beibehaltung einer ROWID darin, zu vermeiden, dass eine teure Operation wiederholt wird, um die Zeile beispielsweise in einer sehr großen Tabelle zu finden. Trotzdem ist die Leistung in vielen Fällen akzeptabel. Wenn Microsoft das Optimierungsprogramm in einer zukünftigen Version anpasst, kann das Leistungsproblem behoben werden.
Es ist auch möglich, FOR UPDATE einfach zu verwenden und den CURSOR in einem prozeduralen Programm offen zu halten. Dies könnte sich jedoch bei der Verarbeitung großer oder komplexer Chargen als teuer erweisen.
Vorsichtsmaßnahme: Selbst die ROWID von Oracle wäre nicht stabil, wenn der DBA zwischen SELECT und UPDATE beispielsweise die Datenbank neu erstellen würde, da es sich um die physische Zeilen-ID handelt. Das ROWID-Gerät sollte daher nur innerhalb einer gut definierten Aufgabe verwendet werden.
quelle
Wenn Sie nur eine einfache Zeilennummerierung für einen kleinen Datensatz wünschen, wie wäre es dann mit so etwas?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
quelle
Von http://vyaskn.tripod.com/programming_faq.htm#q17 :
quelle
Wenn Sie die Zeilen in der Tabelle dauerhaft nummerieren möchten, verwenden Sie bitte nicht die RID-Lösung für SQL Server. Es ist schlechter als Access auf einem alten 386. Erstellen Sie für SQL Server einfach eine IDENTITY-Spalte und verwenden Sie diese Spalte als Cluster-Primärschlüssel. Dadurch wird ein permanenter, schneller Integer-B-Baum in die Tabelle eingefügt, und was noch wichtiger ist, jeder nicht gruppierte Index verwendet ihn zum Auffinden von Zeilen. Wenn Sie versuchen, in SQL Server so zu entwickeln, als wäre es Oracle, erstellen Sie eine Datenbank mit schlechter Leistung. Sie müssen für den Motor optimieren und nicht so tun, als wäre es ein anderer Motor.
Verwenden Sie außerdem nicht die NewID (), um den Primärschlüssel mit GUIDs zu füllen. Andernfalls wird die Leistung beim Einfügen beeinträchtigt. Wenn Sie GUIDs verwenden müssen, verwenden Sie NewSequentialID () als Spaltenstandard. Aber INT wird immer noch schneller sein.
Wenn Sie andererseits einfach die Zeilen nummerieren möchten, die sich aus einer Abfrage ergeben, verwenden Sie die Funktion RowNumber Over () als eine der Abfragespalten.
quelle
Bitte versuche
select NEWID()
Quelle: https://docs.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql
quelle
ROWID ist eine versteckte Spalte in Oracle-Tabellen. Erstellen Sie daher für SQL Server eine eigene Spalte. Fügen Sie eine Spalte mit dem Namen ROWID mit dem Standardwert von hinzu
NEWID()
.Vorgehensweise: Fügen Sie der vorhandenen Tabelle in SQL Server eine Spalte mit dem Standardwert hinzu
quelle
Weitere Informationen finden Sie unter http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx. In SQL Server entspricht ein Zeitstempel nicht einer DateTime-Spalte. Dies wird verwendet, um eine Zeile in einer Datenbank eindeutig zu identifizieren, nicht nur eine Tabelle, sondern die gesamte Datenbank. Dies kann für eine optimistische Parallelität verwendet werden. Beispiel: UPDATE [Job] SET [Name] = @ Name, [XCustomData] = @ XCustomData WHERE ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp AND [GUID] = @ Original_GUID
Der ModifiedTimeStamp stellt sicher, dass Sie die Originaldaten aktualisieren, und schlägt fehl, wenn die Zeile erneut aktualisiert wurde.
quelle
Ich habe dieses Beispiel aus dem MS SQL-Beispiel genommen und Sie können sehen, dass die @ID mit einer Ganzzahl oder einem Varchar oder was auch immer ausgetauscht werden kann. Dies war die gleiche Lösung, nach der ich gesucht habe, also teile ich sie. Genießen!!
-- UPDATE statement with CTE references that are correctly matched. DECLARE @x TABLE (ID int, Stad int, Value int, ison bit); INSERT @x VALUES (1, 0, 10, 0), (2, 1, 20, 0), (6, 0, 40, 0), (4, 1, 50, 0), (5, 3, 60, 0), (9, 6, 20, 0), (7, 5, 10, 0), (8, 8, 220, 0); DECLARE @Error int; DECLARE @id int; WITH cte AS (SELECT top 1 * FROM @x WHERE Stad=6) UPDATE x -- cte is referenced by the alias. SET ison=1, @id=x.ID FROM cte AS x SELECT *, @id as 'random' from @x GO
quelle
Sie können die ROWID mithilfe der folgenden Methoden abrufen:
1.Erstellen Sie eine neue Tabelle mit einem Feld für die automatische Inkrementierung
2.Verwenden Sie die Analysefunktion Row_Number, um die Sequenz basierend auf Ihren Anforderungen zu erhalten. Ich würde dies bevorzugen, da dies in Situationen hilfreich ist, in denen Sie möchten, dass die row_id in aufsteigender oder absteigender Weise eines bestimmten Felds oder einer Kombination von Feldern angezeigt wird
Beispiel: Row_Number () Over (Partition nach Deptno Reihenfolge nach sal desc)
Das obige Beispiel gibt Ihnen die Sequenznummer basierend auf dem höchsten Gehalt jeder Abteilung. Die Aufteilung nach ist optional und Sie können sie gemäß Ihren Anforderungen entfernen
quelle