【转】如何从SharePoint Content DB中查询List数据***

SharePoint用来维护基础数据非常方便,只需要建立自定义列表,然后使用InfoPath自定义一下维护界面,就可以实现在线的增删改查,开发效率很高。如果维护的数据需要进行审批,还可以加入工作流功能。使用SharePoint Designer可以快速开发出简单的工作流,如果是很复杂的工作流,那么就需要使用VS进行开发了。现在数据已经维护进了SharePoint List,那么怎么从数据库中将维护的数据查询出来呢?

SharePoint 的列表数据都存储在Content DB中,其中最最重要的表就是[dbo].[AllUserData],这个表中的一行数据就对应SharePoint List中的一条数据。下面介绍下如何从Content DB中查询出List数据。

Case 1简单数据类型的自定义列表查询

假设我们现在有一个Country列表,记录了全球200多个国家和地区的中文名,英文名,建国日期,面积,人口等信息,整个列表只有字符串、日期、数字等简单类型,没有User,Lookup等数据类型,则整个List的数据都可以从[dbo].[AllUserData]查询获得,具体查询步骤:

1. 查询[dbo].[AllLists]找到ListId。

select *
from [dbo].[AllLists]
where</span> tp_Title ='Country'

由于整个网站集都是共用一个Content DB数据库,所以可能会出现在多个网站中都创建了Country这个List的情况,那么就会返还多条结果,这个情况下,就需要关联AllWebs表,根据网站的Url来判断到底哪个ListId才是我们需要的。

select w.FullUrl,l.tp_ID
from [dbo].[AllLists] l
inner join [dbo].[AllWebs] w on l.tp_WebId=w.Id
where l.tp_Title = 'Country'

在找到了ListId后,接下来所有查询都会用到这个Id。

2. 查询[dbo].[AllUserData],找到需要查询的列,并命名为别名。

假设第一步我们查询出来的ListId是'F20E316B-EA24-4164-9437-BBB17C182691',那么我们查询Country这个列表的所有数据的SQL就是:

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> *
<span style="color:#0000ff">FROM</span> AllUserData
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span></span>

这个表的列非常多,在SharePoint 2013的环境中会更多,但是存储数据的列都是用“数据类型+数字”来命名的。所以如果要找建国日期这个字段对应的列,那么就去看datetime1 datetime2等,如果要找面积,人口等数值类型的列,那就去看float1 float2等;如果要找中文名,英文名之类的字符串列,那就要看nvarchar1 nvarchar3等列。这里基本上都是靠眼睛来看的,根据查询的结果推断哪些字段存储了哪些数据。在得知每个字段的对应后,即可修改查询,将别名加上。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span></span>

【注意:SharePoint并没有在数据库中以很方便的结构展现哪些列表字段对应哪个数据库字段,在AllLists表中,虽然有个字段tp_Fields,但是在SharePoint2010及之后,该字段是压缩的二进制,使用SQL是无法读取的。所以根本不可能通过查询数据库得知哪个字段的别名是什么。】参考:http://stackoverflow.com/questions/8988098/how-could-i-find-the-fields-of-a-sharepoint-list-from-database-in-sharepoint-201

3. 过滤掉已删除的数据。

如果数据经过删除,然后又重新录入,那么我们就会发现,第2步的查询结果会把删除的和重新录入的数据都查询出来。SharePoint采用的删除方法都是软删除,通过设置一个标志位来表示一条数据已经被删除,所以我们只需要将删除标识tp_DeleteTransactionId=0添加到where条件中,即可将未删除的数据返回。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0</span>

4. 过滤掉历史版本的数据。

如果这个列表开启了版本控制,那么我们查询的结果可能包含多个版本的数据,而我们只需要最新版本的数据,不希望历史版本数据出现在查询中。AllUserData表中,使用tp_IsCurrentVersion字段来标识这条数据是最新的当前版本还是历史版本。

于是,查询最新版本的SQL改为:

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 </span>

5. 过滤掉内容审批未通过的数据。

如果这个列表开启了内容审批,那么就会出现多个最新版本的情况,一个是已经被审批通过的版本,另一个是修改后还没有进行审批的版本。一般来说,我们是希望只有审批通过的才查询出来,用户进行修改后,只要审批状态不是Approve,那么就不应该出现在查询结果中。在AllUserData表中,使用tp_ModerationStatus字段来标识这行数据是否已经被审批通过。这是一个枚举类型,其值为:

0 The list item is approved. 
1 The list item has been denied approval. 
2 The list item is pending approval. 
3 The list item is in the draft or checked out state. 
4 The list item is scheduled for automatic approval at a future date.

这里,我们只要审批通过的数据,所以我们的SQL更新为:

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

Case 2引用(Lookup)其他列表的自定义列表查询

若要将关系数据维护到SharePoint中,那么Lookup数据类型是非常常用的实现方法。使用Lookup可以很容易实现一对多和多对多关系,关于多对多关系,我们在Case3中再进行讲解,先看看一对多关系的维护与查询。

紧接着Case1,现在我们需要创建一个用户表,里面记录了用户的姓名,生日,出生国等信息,出生国字段对应的就是Lookup Country这个List,用户出生国不能乱填,必须从现有Country中进行选择,而且只能选择一个,这就是典型的一对多关系。

做过数据库设计的都应该知道,对于一对多关系,需要使用一个表添加另一个表的主键来作为外键,如果是数据库表的话,那么User表中必然有个BirthCountryId列。那么在SharePoint中,所有列表都存储在AllUserData表中,那这种关系怎么表示呢?

AllUserData表中有很多int1 int2之类的整型字段,但是这些字段并不用于存储数值类型(数值类型使用float1 float2等存储),而是用于存储Lookup表的外键。查询具有Lookup字段的自定义列表的操作如下:

1. 查询外键表。

这里Country表是User表的外键表,所以先将Country表查出来,查的字段必须包含tp_ID,这个整型主键值就是用作外键关联的。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> d.tp_ID,
d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

2. 查询主表。

对于我们的主表User表,查询方法跟Case1的步骤一样,找到ListId,找到需要的字段,同时需要找到外键的关联字段,也就是int1 int2这种字段。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> 
d.nvarchar1 <span style="color:#0000ff">as</span> UserChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> UserEnglishName,
d.datetime1 <span style="color:#0000ff">as</span> Birthdate,
d.int1 <span style="color:#0000ff">as</span> CountryId
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

3. Join两个查询结果。

现在看来,前两步的查询就像是两个独立的表一样了,那么接下来我们只需要把主表和外键表进行关联查询,即可。比如我们需要查询用户的姓名,生日,出生地国家中文名,那么对应的SQL就是:

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> 
d.nvarchar1 <span style="color:#0000ff">as</span> UserChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> UserEnglishName,
d.datetime1 <span style="color:#0000ff">as</span> Birthdate,
c.ChineseName <span style="color:#0000ff">as</span> BirthCountryChineseName
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span> 
(
<span style="color:#0000ff">SELECT</span> d.tp_ID,
d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 
) c
<span style="color:#0000ff">on</span> d.int1=c.tp_ID
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

当然,我们可以对这个查询进行简化,把不需要查询返回的字段都删掉。

Case 3引用其他列表并可多选的自定义列表查询

前面只是说的一对多情况的关系,但是要在关系数据库中实现多对多关系,那么就需要用到中间表。同样的道理,在SharePoint中,Lookup字段可以设置成多选,那么就变成了多对多关系,对应数据库中使用[dbo].[AllUserDataJunctions]这个表来实现多对多关联。

我们还是用Case2中的用户表和国家表举例,如果我们为用户表添加国籍字段,由于有些国家允许双重国籍,所以用户和国家就变成了多对多关系。与一对多中使用tp_ID进行关联不一样,在多对多关联中,使用的是主表的Doc_Id和Lookup表的tp_ID进行关联。查询步骤如下:

1. 查询被Lookup的表。同Case2,不再累述。

2. 查询主表,需要tp_DocId字段。查询雷同Case2,只是需要多添加一个tp_DocId字段。

3. 查询中间表,主要是tp_DocId和tp_Id两个字段。

中间表的联合主键字段较多,where条件比较复杂,如果主表和Lookup的表只存在一个多对多关系,那么我们可以写成:

<span style="color:#000000"><span style="color:#0000ff">select</span> tp_DocId,tp_Id
<span style="color:#0000ff">from</span> [dbo].[AllUserDataJunctions]
<span style="color:#0000ff">where</span> tp_SourceListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> tp_IsCurrentVersion=1</span>

如果主表和Lookup表存在多个多对多关系,那么我们还需要知道这里要查询的多对多是哪个字段的多对多。关于FieldId,并不能很简单的通过界面看到,我只找到通过代码或者SPCAMLQueryHelper这样的第三方工具才能查看。在得知了FieldId后,我们的查询便可改为:

<span style="color:#000000"><span style="color:#0000ff">select</span> tp_DocId,tp_Id
<span style="color:#0000ff">from</span> [dbo].[AllUserDataJunctions]
<span style="color:#0000ff">where</span> tp_SourceListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_FieldId=<span style="color:#006080">'48DCB501-EBFD-4727-85AE-9CC9A51E73CF'</span></span>

4. 联合查询主表、Lookup表和中间表。

前面三个步骤我们已经得到了三个独立的表查询,接下来我们就可以按照普通的三个表进行Join查询的方式,将结果查询出来。

<span style="color:#000000"><span style="color:#0000ff">select</span> main.*,lkup.ChineseName <span style="color:#0000ff">as</span> Nationality
<span style="color:#0000ff">from</span>
(
<span style="color:#0000ff">SELECT</span> d.tp_DocId,
d.nvarchar1 <span style="color:#0000ff">as</span> UserChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> UserEnglishName,
d.datetime1 <span style="color:#0000ff">as</span> Birthdate
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 
)main
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span>
(
<span style="color:#0000ff">select</span> tp_DocId,tp_Id
<span style="color:#0000ff">from</span> [dbo].[AllUserDataJunctions]
<span style="color:#0000ff">where</span> tp_SourceListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_FieldId=<span style="color:#006080">'48DCB501-EBFD-4727-85AE-9CC9A51E73CF'</span>
)m2m
<span style="color:#0000ff">on</span> main.tp_DocId=m2m.tp_DocId
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span>
(
<span style="color:#0000ff">SELECT</span> d.tp_ID,
d.nvarchar1 <span style="color:#0000ff">as</span> ChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> EnglishName,
d.datetime1 <span style="color:#0000ff">as</span> FoundingDate,
d.float1 <span style="color:#0000ff">as</span> Area,
d.float2 <span style="color:#0000ff">as</span> Population
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'F20E316B-EA24-4164-9437-BBB17C182691'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 
)lkup
<span style="color:#0000ff">on</span> m2m.tp_Id=lkup.tp_ID</span>

【注意:这里使用的都是Inner Join,那是因为我们认为多选的Lookup是必选的,最少需要选一个,如果是允许不选的,那么就需要改写为Left Join。】

Case 4包含用户或用户组类型的自定义列表用户查询

在SharePoint自定义列表的数据类型中,除了前面Case提到的基本数据类型和Lookup类型外,还有比较常用的就是Person or Group类型。SharePoint Content DB的User数据,存储在[dbo].[UserInfo]表中,在AllUserData中,只需要存储User的ID(int类型)即可。UserId和Lookup表一样,是占用的int4 int5这样的int类型的列,但具体是int几那需要根据实际情况用肉眼去看。另外在AllUserData中有两个常用的UserId,那就是tp_Author和tp_Editor,表示该行数据的创建人和修改人。

关于UserInfo表需要注意的是,这个表的主键是[tp_SiteID],[tp_ID],也就是说只通过UserId去Join的话,可能会找到多条数据,在不同的Site中,UserId是可能重复的。

还是以Case2的用户为例,我们希望知道每条用户数据最后是谁编辑的,将编辑者的登录名显示出来。那么我们需要进行如下操作:

1. 查询用户表,并包含tp_Editor列。与Case2相似,这个不再累述。

2. 查询UserInfo表,将该用户表所在的Site作为过滤条件。

关于SiteId,我们可以在AllUserData中找到,就是tp_SiteID字段。

<span style="color:#000000"><span style="color:#0000ff">select</span> tp_ID,tp_Login
<span style="color:#0000ff">from</span> [dbo].[UserInfo] u
<span style="color:#0000ff">where</span> u.tp_SiteID=<span style="color:#006080">'C4994C7F-ABEF-4D61-9126-086EBE8AE4D5'</span></span>

3. 联合查询用户表和UserInfo表,将编辑者的登录名添加到查询结果中。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> 
d.nvarchar1 <span style="color:#0000ff">as</span> UserChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> UserEnglishName,
d.datetime1 <span style="color:#0000ff">as</span> Birthdate,
d.int1 <span style="color:#0000ff">as</span> CountryId,
users.tp_Login <span style="color:#0000ff">as</span> EditorLoginName
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span>
(
<span style="color:#0000ff">select</span> tp_ID,tp_Login
<span style="color:#0000ff">from</span> [dbo].[UserInfo] u
<span style="color:#0000ff">where</span> u.tp_SiteID=<span style="color:#006080">'C4994C7F-ABEF-4D61-9126-086EBE8AE4D5'</span>
) users
<span style="color:#0000ff">on</span> d.tp_Editor=users.tp_ID
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

Case 5包含用户或用户组类型的自定义列表用户组查询

Case4这里只是查询了用户,如果我们添加的是一个用户组的数据,那么就不能再从UserInfo表中进行查询,而是要从[dbo].[Groups]中进行查询。

Groups表的主键和UserInfo很相似,也是[SiteId],[ID]。而且Groups表和UserInfo表的ID使用的是同一套Sequence。也就是说,如果对于某一个SiteId,我们在UserInfo表中有1,2,3这三个ID的用户,那么我们肯定在Groups中找不到同样ID的Group,GroupID和UserID是不会重复的,这样就避免了在关联AllUserData时Confused。

AllUserData表中并没有一个标识说关联的到底是UserInfo表还是Groups表,所以我们在查询时,可能需要将Groups的数据和UserInfo的数据Union起来然后在和AllUserData进行Join查询。

更普遍的情况是,我们其实并不关心Group的信息,我们更希望得到的是AllUserData和GroupMember的列表,这个时候我们就还需要Join [dbo].[GroupMembership]表。

以用户数据表为例,假设我们添加了一个用户或用户组的列“审批人”用以表示该用户的数据由哪些人审批。该列填入的数据都是SharePoint中建立的用户组。那么我们要查询出用户的审批人列表,那么操作如下:

1. 查询用户数据。这里需要关注的是int类型的列,审批人这个字段就存储在int列中。

2. 查询Groups表和GroupMembership表,获得用户组的信息。当然,这里也需要Join到UserInfo表,找到真正的Membership的登录名。

<span style="color:#000000"><span style="color:#0000ff">select</span> g.ID,u.tp_Login
<span style="color:#0000ff">from</span> [dbo].[Groups] g
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span> [dbo].[GroupMembership] gm
<span style="color:#0000ff">on</span> g.ID=gm.GroupId <span style="color:#0000ff">and</span> g.SiteId=gm.SiteId
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span> [dbo].[UserInfo] u
<span style="color:#0000ff">on</span> u.tp_ID=gm.MemberId <span style="color:#0000ff">and</span> u.tp_SiteID=gm.SiteId
<span style="color:#0000ff">where</span> g.SiteId=<span style="color:#006080">'C4994C7F-ABEF-4D61-9126-086EBE8AE4D5'</span></span>

3. 将步骤1、2的查询结果进行Join,便可得到用户的审批人。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> 
d.nvarchar1 <span style="color:#0000ff">as</span> UserChineseName,
d.nvarchar3 <span style="color:#0000ff">as</span> UserEnglishName,
d.datetime1 <span style="color:#0000ff">as</span> Birthdate,
d.int1 <span style="color:#0000ff">as</span> CountryId,
users.tp_Login <span style="color:#0000ff">as</span> Approvers
<span style="color:#0000ff">FROM</span> AllUserData d
<span style="color:#0000ff">left</span> <span style="color:#0000ff">join</span>
(
<span style="color:#0000ff">select</span> g.ID,u.tp_Login
<span style="color:#0000ff">from</span> [dbo].[Groups] g
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span> [dbo].[GroupMembership] gm
<span style="color:#0000ff">on</span> g.ID=gm.GroupId <span style="color:#0000ff">and</span> g.SiteId=gm.SiteId
<span style="color:#0000ff">inner</span> <span style="color:#0000ff">join</span> [dbo].[UserInfo] u
<span style="color:#0000ff">on</span> u.tp_ID=gm.MemberId <span style="color:#0000ff">and</span> u.tp_SiteID=gm.SiteId
<span style="color:#0000ff">where</span> g.SiteId=<span style="color:#006080">'C4994C7F-ABEF-4D61-9126-086EBE8AE4D5'</span>
) users
<span style="color:#0000ff">on</span> d.int4=users.ID
<span style="color:#0000ff">where</span> tp_ListId=<span style="color:#006080">'53B70F07-3A66-4947-8560-05C5CCCE6A21'</span> <span style="color:#0000ff">and</span> d.tp_DeleteTransactionId=0 <span style="color:#0000ff">and</span> d.tp_IsCurrentVersion=1 <span style="color:#0000ff">and</span> tp_ModerationStatus=0 </span>

以上介绍了关于基本类型,Lookup类型,用户和组类型的SharePoint数据库查询方法,对于其他的数据类型都可以当做基本类型来对待:

  • Multiple Text:ntext类型
  • Choose:nvarchar类型
  • Currency:float类型
  • Yes/No:bit类型
  • Hyperlink or Picture:nvarchar类型
  • Calculated:看具体选择的结果类型
  • External Data:nvarchar ntext都会用到
  • Managed Metadata:未研究

以上几个Case的查询已经包含了大部分数据查询的情况,对于不同的数据列表,只需要稍作修改即可从SharePoint数据库中查询维护的列表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【搬石头排序】

据说是2020浪潮笔试 时间限制&#xff1a;C / C 语言 1000 MS&#xff1b;其他语言 3000 MS 内存限制&#xff1a;C / C 语言 131072 KB&#xff1b;其他语言 655360 KB 题目描述&#xff1a; 沙滩按照线型摆放着n个大小不一的球形石头&#xff0c;已知第i个石头的半径为ri&a…

【转】SharePoint Content Database简介

SharePoint作为微软主打的企业Portal平台&#xff0c;功能强大&#xff0c;使用简单&#xff0c;非常的方便。对于很多关系数据&#xff0c;我们可以使用自定义列表来维护&#xff0c;如果是非关系数据&#xff0c;可以使用文档库来维护。另外还可以在上面进行版本维护&#xf…

【LeetCode 2】两数相加(链表)

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

软件测试几个概念 --dev sit uat

DEV环境&#xff1a;DEV顾名思义就是develop&#xff0c;即代码开发的环境。 SIT环境&#xff1a;System Integration Test系统集成测试&#xff0c;开发人员自己测试流程是否走通。 UAT环境&#xff1a;User Acceptance Test用户验收测试&#xff0c;由专门的测试人员验证&…

【LeetCode 629】K个逆序对数组

给出两个整数 n 和 k&#xff0c;找出所有包含从 1 到 n 的数字&#xff0c;且恰好拥有 k 个逆序对的不同的数组的个数。 逆序对的定义如下&#xff1a;对于数组的第i个和第 j个元素&#xff0c;如果满i < j且 a[i] > a[j]&#xff0c;则其为一个逆序对&#xff1b;否则…

VSTS TFS 强制删除签出锁定项 解除 锁定

项目组一哥们走的时候以独占方式迁出了文件&#xff0c;现在其他人都无法修改&#xff0c;管理员似乎也无法将文件解除。经过摸索&#xff0c;找到了一种暴力的方法——直接改数据库。虽然暴力&#xff0c;却能实实在在地解决这个问题。 步骤&#xff1a; 1、连接到TFS数据库…

【NC30】缺失的第一个正整数

描述 给定一个无重复元素的整数数组nums&#xff0c;请你找出其中没有出现的最小的正整数 进阶&#xff1a; 空间复杂度 O(1)&#xff0c;时间复杂度 O(n) 数据范围: -2^31<nums[i]<2^31-1 0<len(nums)<5*10^5 示例1 输入&#xff1a; [1,0,2] 复制返回值…

【NC140 排序】手写快速排序

描述 给定一个长度为 n 的数组&#xff0c;请你编写一个函数&#xff0c;返回该数组按升序排序后的结果。 数据范围&#xff1a; 0 \le n \le 1\times10^30≤n≤1103&#xff0c;数组中每个元素都满足 0 \le val \le 10^90≤val≤109 要求&#xff1a;时间复杂度 O(n^2)O(n2)…

【LCS系列】最长公共子序列和最长公共子串

最长公共子序列&#xff1a; 如果要回溯出整个字符串的答案的话&#xff0c;可以直接看dp[i][len2-1]列&#xff0c;或者dp[len1-1][i]这一行&#xff0c;变化的时候&#xff0c;则代表要选这个字符&#xff0c;然后连起来就可以了。&#xff08;即构造字符串的过程是On的&…

sharepoint文档库文档版本信息操作

SPListItem spDoc oWeb.Lists["共享文档"].GetItemById(DocumentID); SPFileVersionCollection versionColl spDoc.File.Versions; foreach (SPFileVersion version in versionColl) {     //将UTC时间格式转换为本地时间 DateTime versionTime Conv…

【NC14 按之字形顺序打印二叉树】

描述 给定一个二叉树&#xff0c;返回该二叉树的之字形层序遍历&#xff0c;&#xff08;第一层从左向右&#xff0c;下一层从右向左&#xff0c;一直这样交替&#xff09; 数据范围&#xff1a;0 \le n \le 15000≤n≤1500,树上每个节点的val满足 |val| < 100∣val∣<1…

【NC51 合并k个已排序的链表】K路归并

描述 合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。 数据范围&#xff1a;节点总数 0 \le n \le 50000≤n≤5000&#xff0c;每个节点的val满足 |val| < 1000∣val∣<1000 要求&#xff1a;时间复杂度 O(nlogn)O(nlogn) 示例1 输入&#xff1a; [{1…

SharePoint 2010文档库批量下载文档的实现

在SharePoint 2010文档库中&#xff0c;结合单选框&#xff0c;在Ribbon中提供了批量处理文档的功能&#xff0c;比如&#xff0c;批量删除、批量签出、批量签入等&#xff0c;但是&#xff0c;很遗憾&#xff0c;没有提供批量下载&#xff0c;如图: 若选中多个文档后&#xff…

【NC54 三数之和】(待整理)

描述 给出一个有n个元素的数组S&#xff0c;S中是否有元素a,b,c满足abc0&#xff1f;找出数组S中所有满足条件的三元组。 数据范围&#xff1a;0 \le n \le 10000≤n≤1000&#xff0c;数组中各个元素值满足 |val | \le 100∣val∣≤100 空间复杂度&#xff1a;O(n^2)O(n2)&a…

【转】C#执行rar,zip文件压缩的几种方法及我遇到的坑总结

工作项目中需要用到zip压缩解压缩文件&#xff0c;一开始看上了Ionic.Zip.dll这个类库&#xff0c;操作方便&#xff0c;写法简单 对应有个ziphelper类 using Ionic.Zip;public static class ZipHelper{public static void UnZip(string zipPath, string outPath){try{using (…

【LeetCode - 42. 接雨水】

42. 接雨水 难度困难3164 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 […

【转】C#打包文件夹成zip格式(包括文件夹和子文件夹下的所有文件)

C#打包zip文件可以调用现成的第三方dll&#xff0c;事半功倍&#xff0c;而且该dll完全免费&#xff0c;下载地址&#xff1a;SharpZipLib 下载完解压缩后&#xff0c;把 ICSharpCode.SharpZipLib.dll 拷贝到当前项目的目录下&#xff08;如果偷懒的话&#xff0c;可以直接拷贝…

【LeetCode】第283场周赛题解

本场题题目不难&#xff0c;但是力求写出精简优雅的代码&#xff0c;还是有需要学习的地方的。 第一题 力扣 class Solution:def cellsInRange(self, s: str) -> List[str]:ans []a,b,c,d s[0],s[1],s[3],s[4]for i in range(ord(a), ord(c)1):for j in range(int(b),int…

Linq to Sql : 三种事务处理方式

Linq to SQL支持三种事务处理模型&#xff1a;显式本地事务、显式可分发事务、隐式事务。(from MSDN: 事务 (LINQ to SQL))。MSDN中描述得相对比较粗狂&#xff0c;下面就结合实例来对此进行阐述。 0. 测试环境 OSWindows Server 2008 Enterprise sp1IDEVisual Studio 2008, …

【LeetCode - 33】搜索旋转排序数组(二分)

力扣 解题报告&#xff1a; 二分。但是有不少细节要考虑清楚。 所以干脆考虑另一种二分的方式。也就是第二次二分的时候&#xff0c;把两半数组给拼成一个完整的数组&#xff0c;当然下标需要是虚拟的&#xff0c;这一步可以用偏移量取模完成。这样就不需要考虑边界情况了。 …