在SQL Server中,一般我们都会通过 select * from 表 来查询数据,但有时候,为了探索SQL Server的各种机制,需要看到更原始的数据,或者说是希望从更为底层的方式来看数据,那有没什么办法呢?
其实,通过DBCC PAGE,我们不仅能查看表中的数据,而且还会看到很多内部存储的信息,让你了解SQL Server是如何存储这些数据的。
下面就讲讲如何通过DBCC PAGE来查看表中的数据:
--1.先建表 CREATE TABLE test(idd INT NOT NULL,name VARCHAR(10) NULL) INSERT INTO TEST SELECT 1,'abcdefg' UNION ALL SELECT 2,'hijklmn' --SELECT * FROM TEST SELECT * FROM sys.tables WHERE name = 'test' --2.查询元数据 --hobt_id : 72057594043236352 SELECT hobt_id FROM sys.partitions WHERE object_id = object_id('test') /* first_page :0x790500000100 拆分成2部分:0100和79050000 这2部分要翻转,也就是0001 和 00000579 前面表示fileId,后面是pageId,都是16机制的表示方法, 通过calc计算器的转换,就是10进制就是1和1401 */ SELECT first_page --转换值的顺序 FROM sys.system_internals_allocation_units WHERE container_id = 72057594043236352 --3.这里创建一个表,用来存放dbcc page的结果 if exists(select * from sys.tables where name = 'dbcc_page') drop table dbcc_page go create table dbcc_page ( ParentObject varchar(500), Object varchar(2000), Field varchar(1000), Value nvarchar(max) ) go --4.参数分别是数据库名,fileid,pageid,显示格式 --注意:这里是在自己的电脑上实验,用的master数据库,大家不要在正是服务器上尝试 /* --这样会报错,只能采用下面的,建一个存储过程 insert into dbcc_page(ParentObject,Object,Field,Value) DBCC page(master,1,1401,3) with tableresults */ if exists(select * from sys.procedures where name = 'proc_dbcc_page') drop procedure proc_dbcc_page go create procedure proc_dbcc_page as DBCC page(master,1,1401,3) with tableresults go --5.把dbcc page的结果插入到表中 insert into dbcc_page(ParentObject,Object,Field,Value) exec proc_dbcc_page --6.查看数据 select * from dbcc_page --过滤大部分其他元数据,选出表test中的数据,与最上面的数据相一致 select OBJECT, Field, value from dbcc_page where Object like 'Slot%Column%' /* OBJECT Field value Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4 idd 1 Slot 0 Column 2 Offset 0xf Length 7 Length (physical) 7 name abcdefg Slot 1 Column 1 Offset 0x4 Length 4 Length (physical) 4 idd 2 Slot 1 Column 2 Offset 0xf Length 7 Length (physical) 7 name hijklmn */
除了上面所解析的1401页外,我们还可以查看其他的页:
/* DBCC ind: DBCC IND( ['database name'|database id], tablename, indexid, -1 shows all indexes and IAMs, -2 just show IAMs ) PageFID: 页所在的文件号 PagePID: 数据所在文件内的页号 IndexID: 在sys.indexes中的index_id, -1表示所有索引页和IAM页,-2只显示IAM页 PageType:表示页的类型,1是数据页,2是索引页,10是保存页本身的IAM页。 IndexLevel: 是IAM结构的级别。如果0,那么这是索引的叶级别页 */ select name, index_id -- 0 from sys.indexes where object_id = object_id('test') --1.创建表 if exists(select * from sys.tables where name = 'dbcc_ind') drop table dbcc_ind go create table dbcc_ind ( PageFID numeric(20), PagePID numeric(20), IAMFID numeric(20), IAMPID numeric(20), ObjectID numeric(20), IndexID numeric(20), PartitionNumber numeric(20), PartitionID numeric(20), iam_chain_type nvarchar(100), PageType numeric(20), IndexLevel numeric(20), NextPageFID numeric(20), NextPagePID numeric(20), PrevPageFID numeric(20), PrevPagePID numeric(20) ) go --2.建存储过程 if exists(select * from sys.procedures) drop procedure proc_dbcc_ind go create procedure proc_dbcc_ind as dbcc ind(master,test,0) go insert into dbcc_ind exec proc_dbcc_ind --3.一共2页,分别是IAM页1402,数据页1401 select PageFID, PagePID, OBJECTID, IndexID, PartitionNumber, PartitionID, iam_chain_type, PageType, IndexLevel, NextPageFID, --下一页的文件id NextPagePID, --下一页的页id PrevPageFID, PrevPagePID from dbcc_ind