您的位置:首页 > 数据库

利用dbcc writepage命令修改SQL SQLSERVER中的物理页面上的内容

2010-08-23 18:07 537 查看
----------------------------------------------------------------------------

---- 本文为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



备注:
以上演示的是仅仅修改某一行某一列的数据,并且修改后的内容和修改前的内容保持长度一致。



如果修改多列或者修改前后的字段长度不一致;进一步修改整行数据,或者修改整页的数据的话,可能会复杂许多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: