Jaki jest odpowiednik Oracle RowID w SQL Server?
sql
sql-server
tsql
rowid
row-number
John Saunders
źródło
źródło
Odpowiedzi:
Z dokumentów Oracle
Najbliższym odpowiednikiem tego w SQL Server jest ten,
rid
który ma trzy składnikiFile:Page:Slot
.W SQL Server 2008 można to zobaczyć przy użyciu nieudokumentowanej i nieobsługiwanej
%%physloc%%
kolumny wirtualnej. Zwracabinary(8)
wartość z identyfikatorem strony w pierwszych czterech bajtach, następnie 2 bajty dla identyfikatora pliku, a następnie 2 bajty dla lokalizacji boksu na stronie.Aby przekształcić to w bardziej czytelną formę, można użyć funkcji skalarnej
sys.fn_PhysLocFormatter
lubsys.fn_PhysLocCracker
TVFCREATE TABLE T(X INT); INSERT INTO T VALUES(1),(2) SELECT %%physloc%% AS [%%physloc%%], sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot] FROM T
Przykładowe dane wyjściowe
+--------------------+----------------+ | %%physloc%% | File:Page:Slot | +--------------------+----------------+ | 0x2926020001000000 | (1:140841:0) | | 0x2926020001000100 | (1:140841:1) | +--------------------+----------------+
Należy zauważyć, że nie jest to wykorzystywane przez procesor zapytań. Chociaż możliwe jest użycie tego w
WHERE
klauzuliSELECT * FROM T WHERE %%physloc%% = 0x2926020001000100
SQL Server nie będzie bezpośrednio szukać określonego wiersza. Zamiast tego wykona pełne skanowanie tabeli, oceni
%%physloc%%
dla każdego wiersza i zwróci ten, który pasuje (jeśli w ogóle).Aby odwrócić proces wykonywany przez 2 wcześniej wspomniane funkcje i uzyskać
binary(8)
wartość odpowiadającą znanym wartościom Plik, Strona, Slot, można użyć poniższych.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))
źródło
Muszę usunąć bardzo dużą tabelę z wieloma kolumnami, a szybkość jest ważna. Dlatego używam tej metody, która działa dla każdej tabeli:
delete T from (select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T Where T.RowNumber > 1
źródło
Wypróbuj nową funkcję ROW_NUMBER . Działa to tak:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
źródło
Jeśli chcesz jednoznacznie zidentyfikować wiersz w tabeli, a nie zestaw wyników, musisz przyjrzeć się użyciu czegoś w rodzaju kolumny IDENTITY. Zobacz „Właściwość IDENTITY” w pomocy programu SQL Server. SQL Server nie generuje automatycznie identyfikatora dla każdego wiersza w tabeli, tak jak robi to Oracle, więc musisz zadać sobie trud tworzenia własnej kolumny ID i jawnie pobrać ją w zapytaniu.
EDYCJA: dynamiczne numerowanie wierszy zestawu wyników patrz poniżej, ale prawdopodobnie byłby to odpowiednik ROWNUM Oracle i na podstawie wszystkich komentarzy na stronie zakładam, że chcesz rzeczy powyżej. W przypadku SQL Server 2005 i nowszych można użyć nowej funkcji Ranking Functions w celu uzyskania dynamicznej numeracji wierszy.
Na przykład robię to na moje zapytanie:
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
Da tobie:
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
W witrynie support.microsoft.com znajduje się również artykuł dotyczący dynamicznego numerowania wierszy.
źródło
Kilka z odpowiedzi powyżej będzie obejść brak bezpośredniego odniesienia do określonego wiersza, ale nie będzie działać , jeśli zmiany zachodzą do innych wierszy w tabeli. To są moje kryteria, dla których odpowiedzi są technicznie krótkie.
Powszechnym zastosowaniem Oracle ROWID jest zapewnienie (w pewnym stopniu) stabilnej metody wybierania wierszy i późniejszego powrotu do wiersza w celu jego przetworzenia (np. W celu ZAKTUALIZOWANIA). Metoda znajdowania wiersza (łączenia złożone, wyszukiwanie pełnotekstowe lub przeglądanie wiersza po wierszu i stosowanie testów proceduralnych do danych) może nie być łatwo lub bezpiecznie ponownie wykorzystana do zakwalifikowania instrukcji UPDATE.
Wydaje się, że identyfikator RID programu SQL Server zapewnia tę samą funkcjonalność, ale nie zapewnia takiej samej wydajności. To jedyny problem, jaki widzę, i niestety celem zachowania ROWID jest uniknięcie powtarzania kosztownej operacji w celu znalezienia wiersza, powiedzmy, bardzo dużej tabeli. Niemniej jednak wydajność w wielu przypadkach jest akceptowalna. Jeśli firma Microsoft dostosuje optymalizator w przyszłej wersji, można rozwiązać problem z wydajnością.
Można również po prostu użyć FOR UPDATE i pozostawić CURSOR otwarty w programie proceduralnym. Może to jednak okazać się kosztowne przy przetwarzaniu dużych lub złożonych partii.
Ostrzeżenie: Nawet ROWID Oracle nie byłby stabilny, gdyby DBA, na przykład, między SELECT i UPDATE, odbudował bazę danych, ponieważ jest to fizyczny identyfikator wiersza. Dlatego urządzenie ROWID powinno być używane tylko w ramach dobrze określonego zadania.
źródło
jeśli potrzebujesz tylko podstawowej numeracji wierszy dla małego zbioru danych, co powiesz na coś takiego?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
źródło
Od http://vyaskn.tripod.com/programming_faq.htm#q17 :
źródło
Jeśli chcesz trwale ponumerować wiersze w tabeli, nie używaj rozwiązania RID dla SQL Server. Będzie działać gorzej niż Access na starym 386. W przypadku SQL Server po prostu utwórz kolumnę IDENTITY i użyj tej kolumny jako klastrowego klucza podstawowego. Spowoduje to umieszczenie w tabeli trwałego, szybkiego drzewa typu Integer B-Tree, a co ważniejsze, każdy indeks nieklastrowy użyje go do zlokalizowania wierszy. Jeśli spróbujesz programować w SQL Server tak, jakby to był Oracle, utworzysz słabo działającą bazę danych. Musisz zoptymalizować silnik, a nie udawać, że to inny silnik.
również nie używaj NewID () do wypełniania klucza podstawowego identyfikatorami GUID, zabijesz wydajność wstawiania. Jeśli musisz użyć identyfikatorów GUID, użyj wartości NewSequentialID () jako wartości domyślnej kolumny. Ale INT nadal będzie szybszy.
Jeśli z drugiej strony chcesz po prostu ponumerować wiersze, które wynikają z zapytania, użyj funkcji RowNumber Over () jako jednej z kolumn zapytania.
źródło
Proszę spróbować
select NEWID()
Źródło: https://docs.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql
źródło
ROWID to ukryta kolumna w tabelach Oracle, więc w przypadku programu SQL Server utwórz własną. Dodaj kolumnę o nazwie ROWID z domyślną wartością
NEWID()
.Jak to zrobić: Dodaj kolumnę z wartością domyślną do istniejącej tabeli w SQL Server
źródło
Zobacz http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx W serwerze SQL sygnatura czasowa nie jest tym samym, co kolumna DateTime. Służy do jednoznacznej identyfikacji wiersza w bazie danych, a nie tylko tabeli, ale całej bazy danych. Może to służyć do optymistycznej współbieżności. na przykład UPDATE [Job] SET [Name] = @ Name, [XCustomData] = @ XCustomData WHERE ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp AND [GUID] = @ Original_GUID
ModifiedTimeStamp gwarantuje, że aktualizujesz oryginalne dane i zakończy się niepowodzeniem, jeśli kolejna aktualizacja wystąpi w wierszu.
źródło
Wziąłem ten przykład z przykładu MS SQL i widać, że @ID można zamienić z integer lub varchar lub czymkolwiek. To było to samo rozwiązanie, którego szukałem, więc się nim udostępniam. Cieszyć się!!
-- 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
źródło
Możesz uzyskać ROWID, korzystając z poniższych metod:
1. Utwórz nową tabelę z polem automatycznego przyrostu
2. użyj funkcji analitycznej Row_Number, aby uzyskać sekwencję w oparciu o twoje wymagania. Wolałbym to, ponieważ pomaga w sytuacjach, w których chcesz, aby row_id był rosnący lub malejący określonego pola lub kombinacji pól
Przykład: Row_Number () Over (Partition by Deptno order by sal desc)
Powyższa próbka poda numer porządkowy oparty na najwyższym wynagrodzeniu każdego działu. Podział według jest opcjonalny i można go usunąć zgodnie z własnymi wymaganiami
źródło