SQL Server에서 Oracle의 RowID에 해당하는 것은 무엇입니까?
답변
ROWID 의사 열
데이터베이스의 각 행에 대해 ROWID 의사 열은 행의 주소를 반환합니다. Oracle Database rowid 값에는 행을 찾는 데 필요한 정보가 포함되어 있습니다.
- 개체의 데이터 개체 번호
- 행이있는 데이터 파일의 데이터 블록
- 데이터 블록에서 행의 위치 (첫 번째 행은 0)
- 행이있는 데이터 파일입니다 (첫 번째 파일은 1 임). 파일 번호는 테이블 스페이스에 상대적입니다.
SQL Server에서 이것에 가장 가까운 것은 rid
세 가지 구성 요소가있는 것 File:Page:Slot
입니다.
SQL Server 2008에서는 문서화되지 않고 지원되지 않는 %%physloc%%
가상 열을 사용하여 이를 확인할 수 있습니다. 이렇게 binary(8)
하면 처음 4 바이트의 페이지 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%%
각 행을 평가 하고 일치하는 행을 반환합니다 (있는 경우).
앞서 언급 한 2 개의 함수에 의해 수행 된 프로세스를 반대로하고 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 열과 같은 것을 사용해야합니다. 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)하는 (다소) 안정적인 방법을 제공하는 것입니다. 행을 찾는 방법 (복잡한 조인, 전체 텍스트 검색 또는 행 단위 검색 및 데이터에 대한 절차 테스트 적용)은 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에는 행 번호 또는 행 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와 함께 임시 테이블에 저장합니다 . 임시 테이블을 만드는 것은 특히 큰 테이블로 작업 할 때 비용이 많이 듭니다. 테이블에 고유 키가 없으면이 방법을 사용하십시오.