现在的位置: 首页 > 综合 > 正文

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

2013年09月09日 ⁄ 综合 ⁄ 共 6299字 ⁄ 字号 评论关闭

----------------------------------------------------------------------------

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

 

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

 

如果修改多列或者修改前后的字段长度不一致;进一步修改整行数据,或者修改整页的数据的话,可能会复杂许多。

 

 

 

 

 

【上篇】
【下篇】

抱歉!评论已关闭.