Что эквивалентно Oracle RowID в SQL Server?
sql
sql-server
tsql
rowid
row-number
Джон Сондерс
источник
источник
Ответы:
Из документов Oracle
Ближайшим эквивалентом этого в SQL Server является то,
rid
что состоит из трех компонентовFile:Page:Slot
.В SQL Server 2008 можно использовать недокументированный и неподдерживаемый
%%physloc%%
виртуальный столбец, чтобы увидеть это. Это возвращаетbinary(8)
значение с идентификатором страницы в первых четырех байтах, затем 2 байта для идентификатора файла, а затем 2 байта для местоположения слота на странице.Скалярная функция
sys.fn_PhysLocFormatter
илиsys.fn_PhysLocCracker
TVF могут использоваться для преобразования этого в более читаемую форму.CREATE TABLE T(X INT); INSERT INTO T VALUES(1),(2) SELECT %%physloc%% AS [%%physloc%%], sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot] FROM T
Пример вывода
+--------------------+----------------+ | %%physloc%% | File:Page:Slot | +--------------------+----------------+ | 0x2926020001000000 | (1:140841:0) | | 0x2926020001000100 | (1:140841:1) | +--------------------+----------------+
Обратите внимание, что это не используется обработчиком запросов. Хотя это можно использовать в
WHERE
разделеSELECT * FROM T WHERE %%physloc%% = 0x2926020001000100
SQL Server не будет напрямую искать указанную строку. Вместо этого он выполнит полное сканирование таблицы, оценит
%%physloc%%
каждую строку и вернет ту, которая соответствует (если есть).Чтобы отменить процесс, выполняемый двумя ранее упомянутыми функциями, и получить
binary(8)
значение, соответствующее известным значениям File, Page, Slot, можно использовать следующее.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))
источник
Мне нужно вывести очень большую таблицу со многими столбцами, и скорость важна. Поэтому я использую этот метод, который работает для любой таблицы:
delete T from (select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T Where T.RowNumber > 1
источник
Ознакомьтесь с новой функцией ROW_NUMBER . Это работает так:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
источник
Если вы хотите однозначно идентифицировать строку в таблице, а не свой набор результатов, вам нужно использовать что-то вроде столбца IDENTITY. См. «Свойство IDENTITY» в справке SQL Server. SQL Server не создает автоматически идентификатор для каждой строки в таблице, как это делает Oracle, поэтому вам придется создать собственный столбец идентификатора и явно получить его в своем запросе.
РЕДАКТИРОВАТЬ: для динамической нумерации строк набора результатов см. Ниже, но это, вероятно, было бы эквивалентом Oracle ROWNUM, и я предполагаю, что из всех комментариев на странице вы хотите, чтобы материал был выше. Для SQL Server 2005 и более поздних версий вы можете использовать новую функцию Ranking Functions для динамической нумерации строк.
Например, я делаю это по своему запросу:
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
Даст тебе:
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
На сайте support.microsoft.com также есть статья о динамической нумерации строк.
источник
Некоторые из приведенных выше ответов будут работать с отсутствием прямой ссылки на конкретную строку, но не будут работать, если изменения произойдут в других строках в таблице. Это мои критерии, ответы на которые технически недостаточны.
Обычно ROWID используется для предоставления (в некоторой степени) стабильного метода выбора строк и последующего возврата к строке для ее обработки (например, для ее ОБНОВЛЕНИЯ). Метод поиска строки (сложные объединения, полнотекстовый поиск или просмотр строка за строкой и применение процедурных тестов к данным) может быть нелегко или безопасно повторно использовать для квалификации оператора UPDATE.
Кажется, что RID SQL Server предоставляет те же функции, но не обеспечивает такой же производительности. Это единственная проблема, которую я вижу, и, к сожалению, цель сохранения ROWID - избежать повторения дорогостоящей операции по поиску строки, скажем, в очень большой таблице. Тем не менее, производительность во многих случаях приемлема. Если Microsoft настроит оптимизатор в будущем выпуске, проблема производительности может быть решена.
Также можно просто использовать FOR UPDATE и оставить КУРСОР открытым в процедурной программе. Однако это может оказаться дорогостоящим при большой или сложной пакетной обработке.
Предостережение: даже ROWID Oracle не был бы стабильным, если бы администратор базы данных, например, между SELECT и UPDATE, перестроил базу данных, потому что это физический идентификатор строки. Таким образом, устройство ROWID следует использовать только в рамках хорошо поставленной задачи.
источник
если вам просто нужна базовая нумерация строк для небольшого набора данных, как насчет чего-то вроде этого?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
источник
С http://vyaskn.tripod.com/programming_faq.htm#q17 :
источник
Если вы хотите постоянно нумеровать строки в таблице, пожалуйста, не используйте решение RID для SQL Server. Он будет работать хуже, чем Access на старом 386. Для SQL Server просто создайте столбец IDENTITY и используйте этот столбец в качестве кластеризованного первичного ключа. Это поместит в таблицу постоянное быстрое целочисленное B-дерево, и, что более важно, каждый некластеризованный индекс будет использовать его для поиска строк. Если вы попытаетесь разработать SQL Server, как если бы это был Oracle, вы создадите плохо работающую базу данных. Вам нужно оптимизировать для движка, а не делать вид, что это другой движок.
также, пожалуйста, не используйте NewID () для заполнения первичного ключа идентификаторами GUID, это снизит производительность вставки. Если вы должны использовать GUID, используйте NewSequentialID () в качестве столбца по умолчанию. Но INT все равно будет быстрее.
С другой стороны, если вы просто хотите пронумеровать строки, полученные в результате запроса, используйте функцию RowNumber Over () в качестве одного из столбцов запроса.
источник
Пожалуйста, попробуй
select NEWID()
Источник: https://docs.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql
источник
ROWID - это скрытый столбец в таблицах Oracle, поэтому для SQL Server создайте свой собственный. Добавьте столбец с именем ROWID со значением по умолчанию
NEWID()
.Как это сделать: добавить столбец со значением по умолчанию в существующую таблицу в SQL Server
источник
См. Http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx В SQL-сервере метка времени отличается от столбца DateTime. Это используется для уникальной идентификации строки в базе данных, а не только таблицы, но и всей базы данных. Это можно использовать для оптимистичного параллелизма. например UPDATE [Job] SET [Name] = @ Name, [XCustomData] = @ XCustomData WHERE ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp И [GUID] = @ Original_GUID
ModifiedTimeStamp гарантирует, что вы обновляете исходные данные, и завершится ошибкой, если в строке произошло другое обновление.
источник
Я взял этот пример из примера MS SQL, и вы можете видеть, что @ID можно поменять местами с целым числом, varchar или чем-то еще. Это было то же самое решение, которое я искал, поэтому я делюсь им. Наслаждаться!!
-- 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
источник
Вы можете получить ROWID, используя методы, указанные ниже:
1.Создайте новую таблицу с полем автоинкремента в ней
2.Используйте аналитическую функцию Row_Number, чтобы получить последовательность, основанную на ваших требованиях. Я бы предпочел это, потому что это помогает в ситуациях, когда вы хотите, чтобы row_id был в порядке возрастания или убывания определенного поля или комбинации полей
Пример: Row_Number () Over (Разделение по порядку Deptno по sal desc)
В приведенном выше примере будет указан порядковый номер, основанный на наивысшей заработной плате каждого отдела. Разделение по необязательно, и вы можете удалить его в соответствии с вашими требованиями.
источник