存档
dbcc writepage是sqlserver 2000 和 2005中未公开的命令,也就是说使用这些未官方支持的命令出现的任何后果与MS无关。
同样,本文仅仅演示dbcc writepage的使用,您在操作时出现的任何后果与本人无关。
dbcc writepage的语法为:
dbcc writepage ({ dbid, ‘dbname’ }, fileid, pageid, offset, length, data)
下面演示dbcc writepage的使用方法:
----------------------------------------------------------------------------
第一步:创建一个测试表
1> create table test (id int not null,name varchar(30) null)
2> 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
备注: 以上演示的是仅仅修改某一行某一列的数据,并且修改后的内容和修改前的内容保持长度一致。
如果修改多列或者修改前后的字段长度不一致;进一步修改整行数据,或者修改整页的数据的话,可能会复杂许多。
————————————————————————————————-
—- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
—- 转载务必注明原始出处 : http://www.dbainfo.net
—- 关键字:dbcc writepage undocumented command 修改 物理页面 page
————————————————————————————————-