什么是(含义)Type =’P’,为什么要使用未记录的master..spt_values来分割列?它的好处是什么?
[1]
CREATE TABLE dbo.Table1 ( Col1 CHAR(1),Col2 CHAR(1),Col3 CHAR(1),Col4 VARCHAR(50) ) GO INSERT INTO dbo.Table1 VALUES ('A','B','C','1,2,3') GO INSERT INTO dbo.Table1 VALUES ('D','E','F','6,7,8,9') GO SELECT T.col1,RIGHT(LEFT(T.col4,Number-1),CHARINDEX(',',REVERSE(LEFT(','+T.col4,Number-1)))) FROM master..spt_values,table1 T WHERE Type = 'P' AND Number BETWEEN 1 AND LEN(T.col4)+1 AND (SUBSTRING(T.col4,Number,1) = ',' -- OR SUBSTRING(T.col4,1) = '') --this does not work correctly anyway
相关问题:
解决方法
为什么使用未记录的master..spt值
Sybase,因此它的混蛋儿子MS sql为产品提供了各种功能和功能,这些功能和功能是在系统过程中实现的(而不是像sqlserver这样的二进制文件,作为服务启动).这些系统过程过程用sql代码编写并命名为sp_%.除了一些秘密内部机构,它们与其他sql代码具有相同的限制和需求.它们是Sybase ASE或sql Server产品的一部分.因此,它们不需要记录;内部位不能被合理地标记为“未记录”.
master..spt_values包含所有系统过程在sql表中需要的各种不同的部分,以生成各种报告. sp是系统程序; spt表示系统程序表;当然,价值观是内容.
查找表
什么是(含义)Type =’P’
人们经常将spt_values描述为“正规化”,但这是不正确的术语.正确的术语是折叠或包装的.它是26个左右的逻辑查找表,每个精美的规范化,折叠成一个物理表,使用“类型”列来区分逻辑表.
现在在正常的数据库中,这将是一个严重的错误(只是看一下“一个查找表或许多”的答案).但是在服务器目录中,最好替换26个物理表.
>“L”代表LockType Lookup; “V”表示DeviceType Lookup(V为整个服务器中的Device为简称);类型“P2”包含按位序号,用于扩展打包成INT的位.
>已知边界中的一组连续的数字,以sql表的形式提供是必需的,以便执行许多系统过程必须执行的“投影”.类型“P”是0到2047之间的连续数字的列表.
>术语“投影”在这里被用作技术上精确的意义,自然的逻辑意义,而不是关系代数的意义,这是不自然的.
因此,只有spt_values的一个目的是包含26个折叠的,另外分开的参考表和一个Projection表.
扩张
通常使用spt_values,就像普通的Lookup或Reference或ENUM表.首先,Lookup值:
SELECT * -- list Genders FROM Gender
它的使用方式与Person具有需要扩展的GenderCode(非常扩展,这些奇怪的日子)相同:
SELECT P.*,-- list Person G.Name -- expand GenderCode to Name FROM Person P JOIN Gender G ON P.GenderCode = G.GenderCode
例如. sp_lock生成活动锁的报告,显示锁类型作为字符串名称.但是master..slocks包含锁定类型作为数字,它不包含这些名称;如果这样做,那将是一个严重的非正规化表!如果执行查询(Sybase ASE代码,则必须转换):
SELECT * -- list LockTypes FROM master..spt_values WHERE type = "L"
您将在Lookup表中注意到66个LockType数字和名称.这允许sp_lock执行像Person :: Gender之类的简单代码:
SELECT spid,-- list Active Locks DB_NAME(dbid),OBJECT_NAME(id,dbid),v.name,-- expand lock name page,row FROM master..syslocks L,master..spt_values LT WHERE L.type = LT.number -- AND type = "L" -- LockType Lookup table ORDER by 1,3,4,5,6 -- such that perusal is easy
投影
什么是(含义)Type =’P’?
什么是投影,它是如何使用的?
比如说,而不是上面查询产生的活动锁,你想要一个所有66 LockTypes的列表,显示活动锁(或Null)的数量.您不需要光标或WHILE循环.我们可以通过活动锁的计数来设置LockType查找表:
SELECT LT.name,-- list LockTypes [Count] = ( -- with count SELECT COUNT(*) FROM master..syslocks WHERE type = LT.number ) FROM master..spt_values LT WHERE type = "L"
有几种方法,只有一种.另一种方法是使用派生表而不是子查询.但是你仍然需要投影.
这通常是spt_values用于扩展或投影.现在你知道它在那里,你也可以使用它.它是安全的(在主数据库中),并被几乎所有的系统过程所使用,这意味着系统过程无法运行.
分割列?
啊,你不明白“将一个CSV列分割成多行”代码.
>暂时忘记spt_values,再次检查该代码.它只需要一个连续数字的列表,以便可以逐个逐字节地逐列CSV列中的值列表.该代码只对每个字节都是激活,逗号或字符串结尾.
>在哪里可以以sql表的形式获取一组连续的数字,而不是从头开始创建一个数组,并将其插入到其中?为什么,master..spt_values当然是.如果你知道它在那里
(您可以通过阅读系统存储过程的代码了解一下ASE或sql Server的内部部分.)
>请注意,一列中的任何CSV字段都是总标准化错误,它打破2NF(包含重复值)和1NF(不是原子).注意,这是不包装或折叠的,它是一个重复组,它是不规范化的.这种严重错误的许多负面后果之一是,不是使用简单的sql将重复组导航为行,而是必须使用复杂代码来确定和提取未规范化的CSV字段的内容.这里spt_values P为该复杂代码提供了一个向量,使其更容易.
它的好处是什么?
我想我已经回答了.如果没有,则需要数字列表的每个系统过程都必须创建一个临时表;并将行插入其中;在运行代码之前.当然,没有必要执行这些步骤,使系统程序更快.
现在,当您需要执行投影时,例如.日历日期,或任何您可以使用spt_values,而不必每次创建自己的临时表(或创建您自己的私人永久表并维护它).