SQL Server中Oracle的RowID等于什么?
Answers:
ROWID伪列
对于数据库中的每一行,ROWID伪列返回该行的地址。Oracle Database rowid值包含查找行所必需的信息:
- 对象的数据对象编号
- 该行所在的数据文件中的数据块
- 该行在数据块中的位置(第一行为0)
- 该行所在的数据文件(第一个文件为1)。文件号是相对于表空间的。
在SQL Server中与此最接近的等效项是rid
具有三个组成部分的File:Page:Slot
。
在SQL Server 2008中,可以使用未记录且不受支持的%%physloc%%
虚拟列进行查看。这将返回一个binary(8)
值,其中页面ID的前四个字节,然后是文件ID的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))
签出新的ROW_NUMBER函数。它是这样的:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
如果要唯一标识表中的行而不是结果集,则需要使用IDENTITY列之类的东西。请参阅SQL Server帮助中的“ IDENTITY属性”。SQL Server不会像Oracle那样为表中的每一行自动生成一个ID,因此您必须麻烦创建自己的ID列并在查询中显式获取它。
编辑:对于结果集行的动态编号,请参见下文,但这可能与Oracle的ROWNUM等效,我从页面上的所有注释中假设您想要上面的内容。对于SQL Server 2005和更高版本,您可以使用新的排名函数来实现行的动态编号。
例如,我对我的查询执行此操作:
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上还有关于动态编号行的文章。
上面的几个答案将解决缺少对特定行的直接引用的问题,但是如果表中的其他行发生更改,则将无法工作。这是我的答案在技术上不足的标准。
Oracle ROWID的常见用法是提供一种(某种)稳定的方法来选择行,然后再返回到该行以对其进行处理(例如,对其进行更新)。查找行的方法(复杂的联接,全文搜索或逐行浏览并针对数据应用过程测试)可能不容易或安全地重新用于限定UPDATE语句。
SQL Server RID似乎提供了相同的功能,但没有提供相同的性能。这是我所看到的唯一问题,不幸的是,保留ROWID的目的是避免重复执行昂贵的操作以在一个很大的表中找到该行。尽管如此,许多情况下的性能还是可以接受的。如果Microsoft在将来的版本中调整优化器,则可以解决性能问题。
也可以简单地使用FOR UPDATE并在程序程序中保持CURSOR打开。但是,这可能在大型或复杂的批处理中很昂贵。
注意:例如,如果SELECT和UPDATE之间的DBA重建数据库,则Oracle的ROWID也将不稳定,因为它是物理行标识符。因此,ROWID设备应仅在范围明确的任务中使用。
如果您只想为一个小的数据集进行基本的行编号,那么这种方法怎么样?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
来自http://vyaskn.tripod.com/programming_faq.htm#q17:
Oracle具有一个rownum来使用行号或行id访问表的行。在SQL Server中有与之等效的东西吗?或者如何在SQL Server中生成带有行号的输出?
在SQL Server中没有直接等效于Oracle的rownum或row id。严格来说,在关系数据库中,表中的行没有排序,并且行ID确实没有意义。但是,如果您需要该功能,请考虑以下三种选择:
IDENTITY
在表中添加一列。使用以下查询为每一行生成一个行号。以下查询为pubs数据库的authors表中的每一行生成一个行号。为了使该查询生效,表必须具有唯一键。
SELECT (SELECT COUNT(i.au_id) FROM pubs..authors i WHERE i.au_id >= o.au_id ) AS RowID, au_fname + ' ' + au_lname AS 'Author name' FROM pubs..authors o ORDER BY RowID
使用临时表方法,将整个结果集以及该
IDENTITY()
函数生成的行ID一起存储到临时表中。创建临时表的成本很高,尤其是在使用大型表时。如果表中没有唯一键,请采用这种方法。
如果要对表中的行进行永久编号,请不要对SQL Server使用RID解决方案。在旧的386上,它的性能将比Access差。对于SQL Server,只需创建一个IDENTITY列,然后将该列用作群集的主键。这将在表上放置一个永久的快速Integer B树,更重要的是,每个非聚集索引都将使用它来定位行。如果您尝试像使用Oracle一样在SQL Server中进行开发,则会创建性能不佳的数据库。您需要针对引擎进行优化,而不是假装它是不同的引擎。
同样,请不要使用NewID()来用GUID填充主键,这样会降低插入性能。如果必须使用GUID,请使用NewSequentialID()作为列的默认值。但是INT仍然会更快。
另一方面,如果您只想对查询结果行进行编号,请使用RowNumber Over()函数作为查询列之一。
请尝试
select NEWID()
来源:https : //docs.microsoft.com/zh-cn/sql/t-sql/data-types/uniqueidentifier-transact-sql
请参阅http://msdn.microsoft.com/zh-cn/library/aa260631(v=SQL.80).aspx 在SQL Server中,时间戳记与DateTime列不同。它用于唯一地标识数据库中的一行,不仅是表,而且还标识整个数据库。这可以用于乐观并发。例如UPDATE [Job] SET [Name] = @ Name,[XCustomData] = @ XCustomData WHERE([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp AND [GUID] = @ Original_GUID
ModifiedTimeStamp可确保您正在更新原始数据,并且如果对该行进行了另一次更新将失败。
我从MS SQL示例中获取了此示例,您可以看到@ID可以与integer或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分析函数根据需要获取序列
Sample:Row_Number()Over(按Deptno顺序按sal desc进行分区)
上面的示例将根据每个部门的最高薪水为您提供序列号.partition by是可选的,您可以根据需要将其删除