반응형
  1. /**********************************************************************************************
    -- 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
반응형

+ Recent posts