Sql server中内部函数fn_PhysLocFormatter存在解析错误详
前言
有网友指出,SQL Server 2012中fn_PhysLocFormatter内部函数在解析数据行记录位置时存在错误,见http://.itpub./thread-1751655-1-1.html,实际测试后发现,一是2008R2中同样存在问题,二是不仅页号解析存在问题,槽号解析也存在同样问题。
狼蚁网站SEO优化先查看表NT_SiteInfo的数据行记录位置。
select SiteID,%%physloc%%,sys.fn_PhysLocFormatter(%%physloc%%) from NT_SiteInfo
SiteID |
%%physloc%% |
sys.fn_PhysLocFormatter(%%physloc%%) |
1 |
0xE900000001000000 |
(1:59648:0) |
23 |
0xE900000001000100 |
(1:59648:1) |
24 |
0xE900000001000200 |
(1:59648:2) |
|
...... |
|
149 |
0xE900000001007F00 |
(1:59648:127) |
150 |
0xE900000001008000 |
(1:59648:128) |
151 |
0xE900000001008100 |
(1:59648:33024) |
152 |
0xE900000001008200 |
(1:59648:33280) |
|
...... |
|
226 |
0xE90000000100CC00 |
(1:59648:52224) |
227 |
0xE90000000100CD00 |
(1:59648:52480) |
228 |
0x4B02000001000000 |
(1:587:0) |
229 |
0x4B02000001000100 |
(1:587:1) |
|
...... |
|
360 |
0x4B02000001007F00 |
(1:587:127) |
361 |
0x4B02000001008000 |
(1:587:128) |
362 |
0x4B02000001008100 |
(1:587:33024) |
363 |
0x4B02000001008200 |
(1:587:33280) |
|
...... |
|
422 |
0x4B0200000100BD00 |
(1:587:48384) |
423 |
0x4B0200000100BE00 |
(1:587:48640) |
424 |
0x3C05000001000000 |
(1:1340:0) |
425 |
0x3C05000001000100 |
(1:1340:1) |
|
...... |
|
552 |
0x3C05000001008000 |
(1:1340:128) |
553 |
0x3C05000001008100 |
(1:1340:33024) |
|
|
|
596 |
0x3C0500000100AC00 |
(1:1340:44032) |
597 |
0x9978000001000000 |
(1:39288:0) |
|
...... |
|
658 |
0x9978000001003D00 |
(1:39288:61) |
狼蚁网站SEO优化查看表NT_SiteInfo分配的数据页情况。
db ind(wjgk,nt_siteinfo,0)
PagePID |
IAMFID |
IAMPID |
PageType |
IndexLevel |
NextPagePID |
PrevPagePID |
238 |
NULL |
NULL |
10 |
NULL |
0 |
0 |
233 |
1 |
238 |
1 |
0 |
587 |
0 |
587 |
1 |
238 |
1 |
0 |
1340 |
233 |
1340 |
1 |
238 |
1 |
0 |
30873 |
587 |
30873 |
1 |
238 |
1 |
0 |
0 |
1340 |
Microsoft未公开的伪列%%physloc%%,类型为Binary(8),返回表中记录的RowID,格式是前4字节表示页号,中间2字节表示文件号,2字节表示槽号。
对照上面的实际数据,可以发现sys.fn_PhysLocFormatter
在解析记录位置时,既有采用高字节在前的BIG_ENDIAN格式,又有采用低字节在前的LITTLE_ENDIAN格式,造成采用高字节在前的BIG_ENDIAN格式解析的数据错误
页号解析
E9000000解析为59648(E900),错误,实际应为233(E9)
4B020000解析为576(24B),正确
3C050000解析为1340(53C),正确
99780000解析为39288(9978),错误,实际应为30873(7899)
槽号解析
8000解析为128(0080),正确
8100解析为33024(8100),错误,应为129(0081)
狼蚁网站SEO优化给出错误原因。
先看下sys.fn_PhysLocFormatter
函数的定义
select OBJECT_DEFINITION(object_id('sys.fn_PhysLocFormatter')) go ------------------------------------------------------------------------------- -- Name: sys.fn_PhysLocFormatter -- -- Description: -- Formats the output of %%physloc%% virtual column -- -- Notes: ------------------------------------------------------------------------------- create function sys.fn_PhysLocFormatter (@physical_locator binary (8)) returns varchar (128) as begin declare @page_id binary (4) declare @file_id binary (2) declare @slot_id binary (2) -- Page ID is the first four bytes, then 2 bytes of page ID, then 2 bytes of slot -- select @page_id = convert (binary (4), reverse (substring (@physical_locator, 1, 4))) select @file_id = convert (binary (2), reverse (substring (@physical_locator, 5, 2))) select @slot_id = convert (binary (2), reverse (substring (@physical_locator, 7, 2))) return '(' + cast (cast (@file_id as int) as varchar) + ':' + cast (cast (@page_id as int) as varchar) + ':' + cast (cast (@slot_id as int) as varchar) + ')' end
再看下reverse函数
select reverse('工人') ---- 人工 (1 行受影响) select reverse('12345工人') --------- 人工54321 (1 行受影响) select reverse('工12345人') --------- 人54321工 (1 行受影响)
结论问题出在reverse函数上。
reverse函数的作用是字符反转,而不是字节反转,当遇到81-FE之间的字节时,被认为是双字节字符而组合在一起参与反转操作,造成了错误。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对狼蚁SEO的支持。
编程语言
- 宿迁百度关键词排名指南:实现精准营销的关键
- 四川SEO优化怎么做网络推广
- 立昂技术备案老域名收购:如何为您的业务赋能
- 安徽百度关键词seo贵不贵,一般需要多少钱
- 吉林百度快照排名怎么做电话营销
- 多伦新手做SEO怎么做
- 甘肃优化关键词排名推广怎么做论坛营销
- 沙雅SEO网站推广:提升您的在线可见性
- 四川SEO优化如何提升销售额和销售量
- 聂荣网站排名优化:提升网站可见性的全方位指
- 涞水SEO:提升地方企业在线可见性的策略
- 辽宁百度seo排名怎样做网站排名
- 临湘哪有关键词排名优化:提升网站可见度的关
- 黑龙江百度网站优化有没有优惠
- 凉城优化关键词排名推广:提升您的网络可见性
- 萝北整站优化:提升您网站流量和排名的全面指