----------------------------------------------------------------------------
---- 本文為andkylee個人原創,請在尊重作者勞動成果的前提下進行轉載;
---- 轉載務必註明原始出處
:
http://blog.csdn.net/andkylee
--- 2010-08-23 17:40:37
---- 關鍵字:dbcc writepage undocumented command 修改 物理頁面 page
----------------------------------------------------------------------------
dbcc writepage是sqlserver 2000 和 2005中未公開的命令,也就是說使用這些未官方支援的命令出現的任何後果與MS無關。
同樣,本文僅僅示範dbcc writepage的使用,您在操作時出現的任何後果與本人無關。
dbcc writepage的文法為:
dbcc writepage ({ dbid, ‘dbname’ }, fileid, pageid, offset, length, data)
下面示範dbcc writepage的使用方法:
----------------------------------------------------------------------------
第一步:建立一個測試表
1>
2>
3> create table test (id int not null,name varchar(30) null)
4> go
1> insert into test
2> select 1,'china'
3> go
(1 行受影響)
1> insert into test
2> select 2,'beijing'
3> go
(1 行受影響)
1> select object_id('test')
2> go
-----------
1877581727
(1 行受影響)
表的ID為: 1877581727。
第二步:查看錶內資料所在的頁面號
1> select * from sysindexes
2> where id = 1877581727
3> go
id status first indid root minlen keycnt groupid dpages
reserved used rowcnt rowmodctr reserved3 reserved4
xmaxlen maxirow OrigFillFactor StatVersion reserved2 FirstIAM impid lockflags
pgmodctr keys
name
statblob
maxlen rows
----------- ----------- -------- ------ -------- ------ ------ ------- ---------
-- ----------- ----------- -------------------- ----------- --------- ---------
------- ------- -------------- ----------- ----------- -------- ------ ---------
----------- -------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------- ----------------
--------------------------------------------------------------------------------
-------------------------------- -----------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------- ----------- -----------
1877581727 0 0x3B4F00
0 0x000000 8 0 1
1 2 2 2 2 0 0
57 0 0 0 0 0x3C4F00 0 0
0 NULL
NULL
NULL
8000 2
(1 行受影響)
查詢屬於test表的第一個資料頁的頁號,在sysindexes表中first列表示對象的第一個實體儲存體頁的頁號:0x384F00,也就是頁號(1:20283)。
第三步:查詢修改前的資料內容
下面查詢修改前頁面(1,20283)上的資料內容。可以看出(1,20283)頁上有2行記錄,這和插入的2行記錄數保持一致。然後,觀察到頁面的頭部有china和beijing的字樣,
這和插入的2行記錄內容“似乎”一致。
下面我用紅色標記了test表中兩行測試資料的內容。1,'china' 2,'beijing'
1> dbcc page(9,1,20283,2)
2> go
DATA:
Memory Dump @0x518FC000
518FC000: 01010400 00800001 00000000 00000800 ?................
518FC010: 00000000 00000200 aa000000 721f8a00 ?............r...
518FC020: 3b4f0000 01000000 92010000 75000000 ?;O..........u...
518FC030: 02000000 00000000 00000000 00000000 ?................
518FC040: 01000000 00000000 00000000 00000000 ?................
518FC050: 00000000 00000000 00000000 00000000 ?................
518FC060: 30000800 01000000
0200fc01 00140063 ?0..............c
518FC070: 68696e61 30000800 02000000
0200fc01 ?hina
0...........
518FC080: 00160062 65696a69 6e670000 21212121 ?...beijing
..!!!!
518FC090: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
518FC0A0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
........... 這些是未分配使用的空間
518FDFC0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
518FDFD0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
518FDFE0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
518FDFF0: 21212121 21212121 21212121 74006000 ?!!!!!!!!!!!!t.`.
OFFSET TABLE:
Row - Offset
1 (0x1) - 116 (0x74)
0 (0x0) - 96 (0x60)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
第四步:修改物理資料頁面的內容
通過上面的dbcc page輸出結果,仔細數了一下,china這列內容的位移為111,將china這五個字元改成aaaa。這是最簡單的。a的asicc為:97(0x61)。
1> db
cc
writepage(9,1,20283,111,5,0x6161616161)
2> go
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
第五步:查看修改後的物理頁面的內容
1> dbcc page(9,1,20283,2)
2> go
DATA:
Memory Dump @0x5002C000
5002C000: 01010400 00820001 00000000 00000800 ?................
5002C010: 00000000 00000200 aa000000 721f8a00 ?............r...
5002C020: 3b4f0000 01000000 92010000 75000000 ?;O..........u...
5002C030: 02000000 00000000 00000000 8234666e ?.............4fn
5002C040: 00000000 00000000 00000000 00000000 ?................
5002C050: 00000000 00000000 00000000 00000000 ?................
5002C060: 30000800 01000000
0200fc01 00140061 ?0..............a
5002C070: 61616161 30000800 02000000
0200fc01 ?aaaa
0...........
5002C080: 00160062 65696a69 6e670000 21212121 ?...beijing
..!!!!
5002C090: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
5002C0A0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
5002C140: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
5002C150: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
..................省略未佔用空間
5002DFE0: 21212121 21212121 21212121 21212121 ?!!!!!!!!!!!!!!!!
5002DFF0: 21212121 21212121 21212121 74006000 ?!!!!!!!!!!!!t.`.
OFFSET TABLE:
Row - Offset
1 (0x1) - 116 (0x74)
0 (0x0) - 96 (0x60)
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯絡。
第六步:通過用戶端工具驗證修改後的資料內容
1> select * from test
2> go
id name
----------- ------------------------------
1 aaaaa
2 beijing
(2 行受影響)
可以看到第一行記錄的name列由china改為了aaaaa
備忘:
以上示範的是僅僅修改某一行某一列的資料,並且修改後的內容和修改前的內容保持長度一致。
如果修改多列或者修改前後的欄位長度不一致;進一步修改整行資料,或者修改整頁的資料的話,可能會複雜許多。