반응형
- /**********************************************************************************************
-- Title : [2k] DBCC PAGE를 이용한 Forward Pointer 확인
-- Reference : dBRang.com
-- Key word : dbcc page, dbcc traceon, 먹깨비(??)가 물어봐서 정리된 내용
**********************************************************************************************/
use master
go
/*
** 기존 main_dB가 있으면 drop
*/
if exists(select * from master.dbo.sysdatabases where name = 'main_dB')
drop database main_dB
go
/*
** main_dB create
*/
create database main_dB
go
/*
** main_dB 선택
*/
use main_dB
go
/*
** 기존 main_T 있으면 drop ㅡㅡ;; dB drop후 create 한거라서 안해도 되겠당..
*/
if object_id('main_T') is not null
drop table main_T
go
/*
** main_T create
*/
create table main_T
(
idx int not null identity(1,1)
, col1 varchar(1600) null
, col2 varchar(1600) null
)
go
/*
** main_T에 데이터 입력
*/
-- 첫행은 나중에 1600 길이의 데이터로 업데이트 시켜 forward pinter를 발생시킬것임.
-- 다머지 행들은 8K인 한 페이지를 가능한 채우기 위해 실행 시킴.
insert into main_T values (replicate('a', 1600), '')
insert into main_T values (replicate('b', 1600), '')
insert into main_T values (replicate('main-babu!', 160), '')
insert into main_T values (replicate('c', 1600), '')
insert into main_T values (replicate('d', 1600), '')
go
/*
** main_T 데이터 확인
*/
select idx, col1, len(col1) as [length of col1], col2 from main_T
go
/*
** 에러 로그 대신 클라이어트에게 결과 반환(이거 안하면 안보여~ ㅡㅡ+)
*/
dbcc traceon(3604)
/*
** ============================================================================
** 여기부터는 변수 사용하였기에 go 나올는 곳까정 돌리~시~오~
** ============================================================================
*/
declare @dB_id int
declare @file_id int
declare @page_id int
declare @str varchar(100)
-- @dB_id 구하기
select @dB_id = dbid from master.dbo.sysdatabases where name = 'main_dB'
-- @file_id 구하기
-- 음.. power함수는 말이쥐 16진수를 10진수로 바꾸기 위해 활용 한겨...
select @file_id = convert(varchar(5),
(convert(int, substring(first, 6, 1)) * power(2, 8))
+ (convert(int, substring(first, 5, 1)))
)
from main_dB.dbo.sysindexes
where id = object_id('main_T') and indid = 0
-- @page_id 구하기
select @page_id = convert(varchar(11),
(convert(int, substring(first, 4, 1)) * power(2, 24))
+ (convert(int, substring(first, 3, 1)) * power(2, 16))
+ (convert(int, substring(first, 2, 1)) * power(2, 8))
+ (convert(int, substring(first, 1, 1)))
)
from main_dB.dbo.sysindexes
where id = object_id('main_T') and indid = 0
-- @dB_id, @file_id, @page_id 확인
-- 아래건 볼때만 사용해...막아 논다..^^;;
-- select @db_id as [dB_id], @file_id as [file_id], @page_id as [page_id]
-- DBCC PAGE() 명령문 @str에 저장
set @str = 'dbcc page(' + convert(varchar(10),@dB_id) + ','
+ convert(varchar(10),@file_id) + ','
+ convert(varchar(10),@page_id) + ',1)'
-- DBCC PAGE()문 실행
-- 결과가 안 나왔다고? 에러 메세지 없으면 "메뉴-쿼리-텍스트로 결과 표시"
-- 선택 후 다시 실행혀~
-- 아님 함~ 여기저기 뒤저봐~~ 바부야~ 캭~
exec (@str)
go
/*
결과 설명) 딴거 보지 말고
Slot 2, Offset 0xcfe
-------------------- 이케 된 부부 찾아보면... main-babo!main-babo!를 볼 수 있을 겨..
찾았남....????
다음에는 main-babo!main-babo!행에서 비워있는 col2를
Your dream to be a DBA could be accomplish~! ...라고 업데이트 할겨....
그럼 기존의 한 행 길이보다 커지기면서 해당 페이지에 더이상 삽입할 공간이 없기에
forward pointer가 발생한다....
요거쥐...킁..
go go go~~
*/
/*
** update for making forward pointer
*/
update main_T
set col2 = replicate('Your dream to be a DBA could be accomplish! ', 34)
where idx = 3
go
/*
** main_T에서 col2의 데이터 확인
*/
select * from main_T
go
반응형