MOSS/Sharepoint RBS概念以及运用

注:原文作者不知道是谁,先收藏了这篇(若有侵权,请留言,删除)

EBS -> External Blob Storage 外部大二进制对象存储
RBS -> Remote Blob Storage 远程大二进制对象存储

这俩概念据我所知,SharePoint领域应用比较广泛,如果你对SharePoint存储结构比较熟悉的话,应该比较好理解,简单的说SharePoint算是一种Web应用程序,我们能够通过网页,上传或者管理数据,比如文档,照片,视频,音频等,这些文件的实际载体是数据库,一般就是微软的SQL Server,在数据库表中,这些文件以二进制对象(文件流一样的东西)存储在某一个字段中。随着数据量增大,数据库体积会越来越庞大,最后影响数据库的性能和运营成本,所以人们开始试图将数据库中的文件流取出来存储到文件系统(例如本地磁盘)上,在SharePoint 2007的时候,EBS诞生了,SharePoint提供了类似于一个接口供开发人员实现,可以让SharePoint能够识别存储到其他位置的数据(非SQL Server)。到了SharePoint 2010的时代,数据库版本已经更新了很多,貌似是从SQL Server 08 SP2版本开始的,具体版本记不清了,数据库本身支持了一种文件的外部存储技术,本质上RBS是SQL Server 2008的API,并且使用了SQL Server 2008中的新的FILESTREAM功能。相当于数据库的接口。所以区别也就比较明显了。可能说的不太对,大体上是这么个意思。

MOSS -》RBS  API -》FileStream (API FileStream均由sql server 实现??)

如果使用SharePoint 2007作为文档管理平台,它很让人诟病的一点就是,SharePoint 2007是将文件本身直接存储在SQL Server数据库(WSS_CONTENT.alldoc/doctostream.docstream)之中。虽然Windows SharePoint Services 3.0 SP1增加了一个External BLOB Storage(EBS)接口,但是微软并没有提供实现,而是需要开发人员自己来实现它。 

SharePoint 2010仍然对EBS提供兼容,但并不推荐使用EBS,推荐的解决方案,乃是使用SQL Server 2008 Remote BLOB Storage(RBS)。 

SQL RBS是一组API,通过RBS,一个SQL Server 2008数据库就不再需要将大二进制数据(BLOB)存储在数据库内部,而是可以存储到外面的某个地方,在数据库里面可能只会存储一个对外部BLOB数据的引用。SQL Server 2008和SQL Server 2008 R2都支持RBS。 

听起来RBS实在是一个很好的东东。但是(总是有但是),RBS仅仅是一组API,换句话说,RBS可以让开发人员利用这组API,开发出一个RBS Provider,真正实现对BLOB数据的存取。如果没有RBS Provider,RBS自己可不会自动的将BLOB存储到某个指定的地方去。不同的RBS Provider,可以让我们将BLOB存储到文件系统、磁盘存储设备、文件服务器等等各种地方,反正不继续放到SQL Server数据库里面就对了。 
  

在你对RBS有了初步认识之后,我们接着介绍SQL Server 2008里面的另外一个新特性:FILESTREAM。下面这句话摘自SQL Server 2008联机丛书:“通过将 varbinary(max) 二进制大型对象 (BLOB) 数据以文件形式存储在文件系统上,FILESTREAM 使 SQL Server 数据库引擎和 NTFS 文件系统成为了一个整体。”所以,FILESTREAM可以让管理员选择将SQL Server数据库里面的varbinary(max)类型BLOB数据,存储到本地NTFS文件系统上。在通过FILESTREAM对BLOB数据进行存取的时候,还能顺便能够享受到数据库事务处理的好处。 

听起来,FILESTREAM和RBS很相似,是不是?但其实,RBS和FILESTREAM是两个不同的东东,它们互不依赖RBS是一组API接口,通过这组API,应用程序就能将BLOB数据存储到数据库之外的某个地方,具体实现由开发人员创建的RBS Provider来完成FILESTREAM是SQL Server 2008内置的一个特性,它能将原本存储在数据库里面的BLOB数据,存储到服务器本地的NTFS文件系统上。 

SharePoint 2010所利用的,是RBS API,而并非FILESTREAM特性。所以,如果没有一个RBS Provider,我们并不能马上就将SharePoint 2010里面存储的文件,存储到数据库之外的某个地方去。但是,既然FILESTREAM特性已经拥有了现成的将数据库中的BLOB数据存储到NTFS文件系统上的能力,为什么不能直接使用FILESTREAM,做一个RBS FILESTREAM Provider,也就是利用FILESTREAM的功能实现的一个RBS Provider呢?这样,岂不是就能将SharePoint 2010中的文件,都存储到NTFS文件系统上了吗? 

微软也想到了,所以,微软以特性包(Feature Pack)的形式,提供了一个RBS FILESTREAM Provider。你可以从这里下载x64版本的RBS FILESTREAM Provider。但是要在SharePoint 2010系统上安装并使用它,也是需要按照一定的步骤来操作的。下面就是具体的操作步骤。 

1、确定SQL Server 2008已经启用了FILESTREAM 

在安装SQL Server 2008时,会有一个步骤提示是否安装FILESTREAM。如果你不确定是否安装了此特性,从SQL Server 2008服务器上打开SQL Server配置管理器,从左边选中"SQL Server 服务",然后从右边的窗格中用鼠标右键点击运行的SQL Server实例,选择"属性"菜单项。 
  

在打开的属性窗口中,选择"FILESTREAM"选项卡,然后选中启用FILESTREAM的选择框,点击"确定"按钮。 
  

打开SQL Server Management Studio,选中左侧的SQL Server实例,然后点击工具栏区域的"新建查询",打开一个查询界面,然后在里面输入下面的SQL语句并执行。 

EXEC sp_configure filestream_access_level, 2 
RECONFIGURE 
 

2、确定要应用RBS FILESTREAM Provider的内容数据库 

由于RBS是基于数据库为单元来启用的,所以你可以选择在哪些SharePoint内容数据库上启用RBS。这意味着,对于SharePoint服务器场里面那些存储文件数量并不多的内容数据库,可能并没有必要为它启用RBS,而那些可能会存储大量文件的内容数据库,则可以启用RBS,有效的优化它们。 

SharePoint 2010系统中,内容数据库与网站的关系是: 

● 一个Web应用程序可以使用一个或多个内容数据库; 
● 在新建Web应用程序时,会为其自动创建一个内容数据库,管理员可以稍后为此Web应用程序创建更多的内容数据库; 
● 在Web应用程序中创建一个网站集时,这个网站集会被存储到Web应用程序的某个内容数据库中; 
● 一个网站集(包括其所包含的首要网站和所有子网站),只能被存储在一个内容数据库中,而不能被分拆存储到多个内容数据库中。 

管理员可以打开SharePoint 2010管理中心的内容数据库管理界面,查看每个Web应用程序所使用的内容数据库,或是为某个Web应用程序添加新的内容数据库。 
 

在下面的示范操作中,我们就为上图中所示的这个名为"WSS_Content"的内容数据库,启用RBS。 

3、配置内容数据库 

在确定了要启用RBS的内容数据库之后,打开SQL Server 2008 Management Studio,找到这个内容数据库,用鼠标右键点击并选择"新建查询"菜单项。 
  

在打开的查询窗口中,输入下面这些SQL语句并执行。 

use [WSS_Content] 
if not exists (select * from sys.symmetric_keys where name = 
N'##MS_DatabaseMasterKey##') create master key encryption by password = 
N'Admin Key Password !2#4'

use [WSS_Content] 
if not exists (select groupname from sysfilegroups where 
groupname=N'RBSFilestreamProvider') alter database [WSS_Content] 
add filegroup RBSFilestreamProvider contains filestream

use [WSS_Content] 
alter database [WSS_Content] add file (name = RBSFilestreamFile, 
filename = 'c:\blobstore') to filegroup RBSFilestreamProvider 

在上面这些SQL指令中,标记为蓝色的,是你在复制了这些指令后,需要按照你的环境中的实际情况,需要修改的部分。"WSS_Content"需要修改为你要启用RBS的内容数据库的实际名称。"c:\blobstore"要修改成你希望用来存放BLOB文件的文件夹路径。从实践角度出发,你需要选择一个位于非系统分区、剩余空间大、速度快、稳定可靠的文件夹。注意,这个文件夹只能是一个本地路径,而不能是网络路径,因为FILESTREAM不支持远程NTFS文件夹,也就是说,这个文件夹是处于 数据库 所在的服务器上的。另外,这个文件夹也不要事先建立好,上面的SQL指令会自动帮你将这个文件夹创建出来。 
  

上述SQL语句执行完毕之后,可以打开资源管理器,确认在SQL Server服务器上,相应的文件夹已经创建成功。 

4、安装RBS FILESTREAM Provider 

下载到的RBS_x64.msi文件复制到SharePoint服务器场中的每一台服务器上,所有的SQL Server数据库服务器和SharePoint服务器上都必须安装此RBS Provider。 

先在SQL Server数据库上和SharePoint服务器上(如果服务器场中有多台SharePoint服务器,则在一台Web前端服务器上),安装RBS FILESTREAM Provider,安装步骤如下。 

以管理员身份运行命令提示符。 
  

在命令提示符窗口中,使用"cd"指令将当前路径设置为"RBS_x64.msi"所在的文件夹,然后输入下面这行指令并执行: 

msiexec /qn /lvx* rbs_install_log.txt /i RBS_X64.msi TRUSTSERVERCERTIFICATE=true FILEGROUP=PRIMARY DBNAME="WSS_Content" DBINSTANCE="sp2010" FILESTREAMFILEGROUP=RBSFilestreamProvider FILESTREAMSTORENAME=FilestreamProvider_1 

上面指令中用蓝色标注的部分,是需要按照你的环境中的实际情况进行修改的部分。"WSS_Content"需要修改为需要启用RBS的内容数据库,"sp2010"需要修改为实际的SQL Server 2008实例名称(如果在安装SQL Server 2008时,你没有使用默认实例名称,那么它的值可能类似"sp2010\express"这样的格式)。对每个内容数据库,都只应该使用msiexec.exe执行一次这条指令。 
  

在你敲入了上面这行很长的指令并敲下回车之后,命令提示符窗口看起来会立即执行完成,但实际上,后台会继续执行RBS Provider的安装程序。你可以打开Windows任务管理器,应该会看到有好几个msiexec.exe进程在执行中。过上一会儿,任务管理器中就不会再显示有几个msiexec.exe在运行(在我的环境中仍会剩下一个另外的msiexec.exe进程),这表明RBS Provider安装过程已经完成。 
 

在RBS Provider安装过程中,它会将log信息写入与"RBS_x64.msi"安装文件同目录的"rbs_install_log.exe"文件。从资源管理器中打开这个log文件,搜索其中是否有如下"Installation completed successfully"之类的信息,这些信息表示"RBS_x64.msi"的安装是成功的。 
  

如果在你的SharePoint服务器场中,只有一台SharePoint服务器,那么按照上面的描述,在它上面安装完RBS FILESTRREAM Provider就完事了。但是如果服务器场中存在多台SharePoint服务器,那么就需要继续在其他的Web前端服务器和应用服务器上,安装RBS FILESTREAM Provider,不过,命令提示符里面的指令需要换成: 

msiexec /qn /lvx* rbs_install_log.txt /i RBS_X64.msi DBNAME="WSS_Content" DBINSTANCE="sp2010" ADDLOCAL="Client,Docs,Maintainer,ServerScript,FilestreamClient,FilestreamServer" 

在RBS FILESTREAM Provider安装到所有服务器上之后,打开SQL Server 2008 Management Studio,刷新内容数据库的Table列表,应该会看到多出来许多名称以"mssqlrbs"开头的,与RBS有关的Table。如果在查询窗口中执行下面的SQL语句,也应该能查询出一些结果。 

select * from dbo.sysobjects where name like 'rbs%' 
  

如果在内容数据库中并没有上面这些Table,运行上面的SQL语句也查询不出任何结果,那么表明RBS Provider并没有正确安装到内容数据库上。如果真是这样,在每台服务器上,打开资源管理器,双击"RBS_x64.msi",然后在出现的安装界面中,使用"卸载"选项先将RBS Provider卸载掉,然后再按照上面的步骤,重新在命令提示符窗口中尝试安装它。 

5、为内容数据库启用RBS FILESTREAM Provider 

终于到了最后一个步骤。在SharePoint服务器上,打开SharePoint 2010 Management Shell,这是一个基于Windows Powershell的命令行管理工具。 
  

在SharePoint 2010 Management Shell中,依次执行下面的指令: 

(1) $cdb = Get-SPContentDatabase "WSS_Content" 
获取到指定的内容数据库(SPContentDatabase)对象实例,绿色所标注的"WSS_Content"需要更换成在你的环境中,实际的内容数据库名称。 

(2) $rbss = $cdb.RemoteBlobStorageSettings 
获取内容数据库的RBS设置(SPRemoteBlobStorageSettings)对象实例。 

(3) $rbss.Installed() 
检查在内容数据库上是否安装了RBS,如果需要,更新相应的属性值。 

(4) $rbss.Enable() 
在内容数据库上启用RBS。 

(5) $pvdName = $rbss.GetProviderNames()[0] 
获取第一个注册到内容数据库上的RBS Provider的名称。 

(6) $rbss.SetActiveProviderName($pvdName) 
为内容数据库设置要激活的RBS Provider。 
  

然后,你可以执行"$rbss"来查看它的一些属性值,如果设置正确,它输出的内容应该如上图所示。 

如果你启用RBS FILESTREAM Provider的内容数据库中,已经存储了一个网站集,那么在你启用了RBS Provider之后,网站集里面的文档,并不会自动的马上通过FILESTREAM,转存到NTFS文件系统上。只有新增的文档才会被存储到NTFS文件系统上,网站集里面之前上载的文档,仍然会保存在内容数据库里面。如果你希望现在将那些旧的文档,统统转存到我们所指定的NTFS文件系统中,那么可以继续在SharePoint 2010 Management Shell中执行下面这个指令: 

(7) $rbss.Migrate() 

如果你希望设置一个文档大小阈值,只有大小超过此阈值的文档,才通过RBS FILESTREAM Provider存储到NTFS文件系统上,而小于此阈值的文档,仍然存储在内容数据库中,那么可以在SharePoint 2010 Management Shell中继续执行下面的指令(假设阈值是1048000字节,也就是1M): 

(8) $rbss.MinimumBlobStorageSize = 1048000 
(9) $rbss.Update() 

上面的这些指令,都是针对一个内容数据库的。如果你有多个内容数据库要启用RBS,那么就对每个内容数据库都执行一遍上述指令。 

6、检查最终效果 

在完成了上述所有操作步骤之后,在SharePoint网站中上载一些文档,然后检查你所设定的NTFS文件夹,里面应该会包含有一些子文件夹,存储着这些文档。

 

WSS和MOSS的区别

Microsoft Office SharePoint Service 2007 是微软最新的企业协作应用和开发平台。简称MOSS,MOSS基于Window SharePonit Service 3.0开发,简称WSS。MOSS是收费的,WSS是免费的,只要拥有了Window Server2003的许可,就可以免费安装WSS。

WSS拥有站点,列表,文档库,文档管理,web part,集群部署,站点内搜索,基于WF的工作流等功能。MOSS扩展实现了增强的文档管理,企业搜索,扩展了工作流,引入了web内容管理,Form Service , Excel Service,个人站点等。

 (以下章节若没有特别强调,则所有内容都适合WSS和MOSS的。所有适合WSS的内容也一定适合MOSS,反之则不然)

WSS对IIS的扩展

         WSS基于标准的asp.net 2.0开发 ,这是WSS开发中要始终记住的一点. 要精通WSS开发,一定要精通asp.net。

         每次新建一个WSS站点,IIS中会同样新建一个网站,我们称这个网站是被WSS扩展后的网站。那么扩展后,发生了什么呢?

         首先,IIS站点的所有文件的处理都被影射为需要asp.net运行引擎处理,而标准的IIS站点只有asp.net本身的文件(如aspx,asmx等)才需要运行引擎处理的,其他文件由IIS直接输出到客户端。

         查看一下站点下的web.config文件,我们看到有这么一项配置:

<httpHandlers>

      <removeverb="GET,HEAD,POST"path="*" />

      <addverb="GET,HEAD,POST"path="*"type="Microsoft.SharePoint.ApplicationRuntime.SPHttpHandler, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

      <addverb="OPTIONS,PROPFIND,PUT,LOCK,UNLOCK,MOVE,COPY,GETLIB,PROPPATCH,MKCOL,DELETE,(GETSOURCE),(HEADSOURCE),(POSTSOURCE)"path="*"type="Microsoft.SharePoint.ApplicationRuntime.SPHttpHandler, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

    </httpHandlers>

HttpHandler是asp.net的一个扩展机制,通过实现一个HttpHandler,可以来直接针对较低层的Request,Response编程,WSS通过实现自己的HttpHandler实现对客户端所有请求文件的处理,并且,通过扩展Http请求(扩展OPTIONS,PROPFIND,PUT,LOCK,UNLOCK,MOVE,COPY等动作),实现文档的在线编辑,在线编辑的实现原理可参考这篇文章:http://www.cnblogs.com/jianyi0115/archive/2007/07/15/818566.html

         注意httpModules节点下的这项配置:

<addname="SPRequest"type="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

         HttpModule也是asp.net的扩展机制,通过实现一个HttpModule,可以切入Http请求的某个阶段做出相应的处理,如身份校验,初始化一些通用模块等。

         WSS通过实现SPRequestModule,切入Http请求,进行一些需要的处理。最重要的是,WSS通过SPRequestModule引入了SPVirtualPathProvider。SPRequestModule的OnInit方法中有这个关键的一句:

    SPVirtualPathProvider provider2 = new SPVirtualPathProvider();

HostingEnvironment.RegisterVirtualPathProvider(provider2);

VirtualPathProvider也是asp.net的扩展机制,通过实现VirtualPathProvider可以控制asp.net页面的提供机制,默认的VirtualPathProvider的实现直接访问服务器硬盘上的文件。WSS通过SPVirtualPathProvider实现了自己的页面Provider机制—WSS站点的页面是由文件系统和数据库联合存储的。

新建一个WSS站点后,它的所有的文件都是放在硬盘上,我们通过SharePonit Designer打开一个WSS站点,可以看到完整的目录结构,这些文件实际上全部都影射到文件系统上的某个文件,这个功能叫做ghost。当我们通过SPD修改了某个文件之后,WSS会把这个修改的文件保存到数据库,这个文件跟原始的文件系统上的文件就脱离关联了,这叫做unghost.通过ghost,WSS做到了是不同的站点可以共享相同的文件,通过unghost,WSS又实现了一个站点对页面的修改不会影响到其他站点.

WSS的一些概念

1)       Farm -- 服务器场

     服务器场是WSS最大的一个概念,整个WSS的所有服务器,包括前端服务器,数据服务器,组成了服务器场,一个服务器场有一个配置数据库,多个内容数据库,多个应用程序..

2)       Application -- 应用程序

应用程序对应IIS的一个站点,它是一个安全和程序文件的独立主体。即一个应用程序可以有自己的用户身份认证机制,有自己独立的一套运行程序文件,一个应用程序会映射到硬盘上的一个独立的目录,一般为C:"Inetpub"wwwroot"wss"VirtualDirectories"里面的某个目录.一个应用程序下可以有多个站点集.

3)       Site Collection -- 站点集

     站点集是一个虚拟的单元,在内容,用户和权限上是独立的. 一个站点集可以有多个子站点.

4)       Web -- 站点

     站点内容和权限的组织单元.一个站点可以有多个子站点,多个列表,文档库,多个页面.站点可以有独立的权限.站点可以有子站点,站点和子站点组成树型关系.子站点的权限默认集成于父站点.

5)       List-列表和文档库

     列表可以理解成一个数据库表,用来存储一些业务数据。一个列表有很多字段。

      WSS3.0的列表可以存放多个内容类型。

6)       ConentType--内容类型

        内容类型可以理解成数据实体,如用户,联系人,日程数据等。一个内容类型包含很多字段。

7)       Field-字段

     可以理解成数据库的字段,Field是WSS整个架构的最底层元素。

WSS的对象模型       

         WSS开发很大一部分工作是需要调用各种WSS中的对象来实现的.常用的对象都放在Microsoft.SharePont这个dll中.我们通常的开发都要从站点集对象开始.

Using(SPSite site = new SPSite(“http://site-name/”))

{

}                

         SPSite和SPWeb对象都是需要释放资源的,如果我们自己构造这两个对象,一定要在代码执行完毕时调用Dispose方法,来释放资源.

         如果我们的代码处于WSS的运行环境之下,即代码直接运行在WSS的页面上,那么我们可以直接从WSS的上下文中获取到相关对象.

SPSIte site = SPContext.Current.Site;

SPWeb web = SPContext.Current.Web;  

SPUser user = SPContext.Current.Web.CurrentUser;    

        上下文对象提供了更好的性能(不需要重复创建对象),并且直接跟当前用户的身份挂钩.上下文对象由运行环境进行资源管理,不需要我们用代码来Dispose.

MOSS2007构建与WSS V3之上,并在其之上加了很多的企业级应用,其关系如下图所示:

原文摘自:http://blog.csdn.net/figerdeng/archive/2010/04/26/5532029.aspx

posted @ 2010-12-20 16:07 Alvin_jstu 阅读(71) | 评论(0) | 编辑

2010年11月25日

SQL SERVER 2005数据库总结

/*

/*

数据库总结:

--查询,是操作中的重点及精华部分,由于业务的多样性,导致查询方案的多样性,但是已有的关系必须通过各种手段在查询中予以表达

--常见查询手段

/*

1.普通查询

    select 结果集列表表达式

    from 值域范围

    where 结果集筛选表达式

    group by 统计结果集分组条件表达式

    order by 结果集排序条件表达式

2.子查询(在查询内部嵌套其它辅助查询的定义,例如:其它查询作为计算列、值域、条件等)

3.联合查询(表联接join table)

    inner join内联接----重点,后续的外联接只在特殊数据情况下使用

    left outer join左外联接

    right outer join右外联接

    full outer join全外联接

4.SQL编程查询,通过编写具有执行逻辑的多行代码来获取希望得到的查询结果或操作结果

    4.1---View视图

    4.2---UDF(User Defined Function)用户定义函数

    4.3---SP(Stored Procedure)存储过程

    4.4---Trigger触发器

    4.5---Cursor游标

    4.6---Transaction事务

*/

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

常见的基本语句:

select 字段 from 表名 where 条件

insert into 表名(字段) values(内容)

update 表名  set 字段=新内容 where 条件

drop from 表名

truncate table 表名--整表清空,不写日志,速度极快但很危险

--我们通常通过主键来删除内容

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

对表格进行处理:

1.创建表格

create table 表名

create table ProdutPriceAndStock--表与表之间的1对1关系

(

    productid int not null primary key foreign key references Product(productid),

    --产品标示号,既当主键有当外键体现了一对一的关系

    price money not null,

    productcount  int not null--产品当前库存数量

 

)

2.删除表格

drop table 表名

3.增加表格字段列

alter table 表名

    add 字段列名 字段类型

4.删除表格字段列

alter table 表名

    drop column 列名

5.修改表格字段列属性

alter table 列名

    alter column 列名 字段属性 约束

6.删除表格字段列约束

alter table 表名

    drop constraint  约束名

7.修改表格字段列约束

alter table 表名

    alter column 列名 字段属性 约束 default 0 for 列名

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

程序段编程

--程序三要素:定义数据容器、赋值、使用

begin--程序段的开始

-----------定义

--declare @局部变量名称 数据类型

--特殊定义 --表数据类型

declare @infotable table

       (

           username nvarchar(20),

           userpwd nvarchar(50)

       )

-----------赋值

set @num=5 ---使用常量来赋值

set @num=(select count(accountid) from AccountInfo)---使用子查询来赋值

select @num=30,@str='hello',@isgood=1,@onechar='X'--同时对多个数据容器赋值,往往针对表中不同字段来赋值

--针对表类型的变量,必须使用操作表数据的语句来赋值

-----------使用

--在服务器端的控制台中输出,笑话ijiyunxing是无人可以看到作为重要的调试手段

 

 

 

--通过简单程序来完成运算及简单的业务逻辑

--大兔3元每只,小兔一元三只,百元买白兔

begin

declare @bigcount int,@smallcount int

declare @infotable table

       (

          大兔数量 int,

          小兔数量 int

       )

set @bigcount=1

set @smallcount=100-@bigcount

while(@bigcount<=100)

    begin

       if((@bigcount*3+@smallcount/3)=100)

           begin

              print '祝贺你找到答案了'

              print '大兔:'+Convert(nvarchar(10),@bigcount)+'只'

              print '小兔:'+Convert(nvarchar(10),@smallcount)+'只'

              insert into @infotable(大兔数量,小兔数量) values(@bigcount,@smallcount)

              break--跳出循环

           end

       else

           begin

              print 'bigcount='+Convert(nvarchar(20),@bigcount)+',非答案'

           end

       set @bigcount=@bigcount+1

       set @smallcount=100-@bigcount

    end

 

select * from @infotable

end

go

 

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

建立视图

目的:创建视图其主要目的是为了查询使用

create view  视图名

as

select .........

单表视图

多表视图---主要考查表的链接

    inner join内联接----重点,后续的外联接只在特殊数据情况下使用

    left outer join左外联接

    right outer join右外联接

    full outer join全外联接

 

--交叉联接

select * from Category as c cross join Product as p

go

--内连接inner join----on,寻找有效地数据对应项

select * from Category as c, Product as p

where c.categoryid=p.p_c_id

go

--

select categoryname as 分类名称 ,count(productid) as 分类数量

from Category as c ,Product as p

where c.categoryid=p.p_c_id

group by categoryname

go

 

select * from Category as c

--full outer全外联接

--left outer左

--right outer右

 join Product as p

 on c.categoryid=p.p_c_id

go

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

 

--UDF user defined function 用户自定义函数

--UDF--标量函数,内嵌表值函数,多语句标志函数

--可以接受参数,完成各种常见的查询任务,根据任务结果的不同性质来合理选用不同的函数方式

--标量函数:查询结果为独立的标量值,例如:数字。文字

--我们希望了解任何一个商品分类的目前产品数量

--可变量:产品分类名称

--查询目标:产品数量---int--标量------------------FN

create function QueryProductCountByCategory---函数名

(@Categoryname nvarchar(10))---形参字段

returns int-----返回值

with encryption---加密

as

begin

    declare @count int --返回变量值

    declare @categoryid nvarchar(15)

    set @categoryid=(select categoryid from Category where categoryname=@categoryname)

    if(@categoryid is null)    

       begin

       set @count=-1--利用无效的返回值来表示参数有误

       end

    else

       begin

       set @count=(select count(productid)from Product where p_c_id=@categoryid)

--得到大于等于0的有效结果值

       end

    return @count

end

go

 

-如果我们查询的目标是一个可以直接得到的结果集表格

--内嵌表值函数------------------------------------IN

 

--我们希望了解任何一个产品分类的所有产品信息,何解

create function QueryProductInfoByCategory---函数名

(@categoryname nvarchar(10))---形参字段

returns table

with encryption

as

return

(select * from ProductInfoView where 分类名=@categoryname)

go

--如果我们发现有时候要得到的结果不方便进行直接查询得到,我们可以将查询过程分散,

使用多于具有标志函数来完成全过程

--使用多语句表值函数------------------------------TF

--Multistatement Table_valued Functions

--我们想要知道目前的有效用户数量,何解

create function QueryAccountInfoByEnable()

returns @infotable table

(数量分类 nvarchar(20),本类数量 int)

with encryption

as

begin

    declare @enablecount int,@disablecount int

    set @enablecount =(select count(accountid)from AccountInfo where [enable]=1)

    set @disablecount=(select count(accountid)from AccountInfo where [enable]=0)

    insert into @infotable(数量分类,本类数量)

    values('有效用户',@enablecount)

    insert into @infotable(数量分类,本类数量)

    values('无效用户',@disablecount)

    return

end

go

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

 

--创建存储过程,接受参数,完成合理的执行过程,执行过程默认可以不提供返回值,默认等效于void方法

--------------SP

 

create procedure RegAccountInfo

       @变量名 变量类型(实参)

with encryption

as

begin

..................

end

go

execute SP名 (形参)

go

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

--触发器:一种特殊的存储过程,满足某些对数据的发生变化的操作条件时会自动执行,

--触发器的设计者需要编写合理的完整代码以表示自动执行的逻辑达到维护数据完整性的要求

1.触发器是绑定在一个表中的

2.触发器的执行条件为:所绑定的表中数据发生了变化,而不是查询

3.常见的触发器的执行时机为:改变的代码在缓存中产生执行效果之后触发

4.触发过程中有两个内部辅助表:inserted与deleted,分别表示本次操作将会加入的新数据及操作中

可能被删除的就数据,任何一次update操作都会同时导致inserted,delected发生改变,着两个表格

的格式与本表完全一致

create trigger AddSaleScoreTrigger

on SaleLog --on后面要写的是绑定表,绑定表的变化导致触发的执行

for insert --描述触发的前提

as

begin

declare @buycount int ,@buyprice money,@buyaccount nvarchar(20)

declare @oldscore money,@newscore money

select @buycount=salecount,

       @buyprice=saleprice,

       @buyaccount=accountid

from inserted --从最新变化的内部数据表中获取关键数据

set @oldscore=(select buyscore from AccountInfo where accountid=@buyaccount)

set @newscore=@oldscore+@buycount*@buyprice

update AccountInfo set buyscore=@newscore

where accountid=@buyaccount

end

go

 

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

/*

游标:针对指定的数据范围,可以进行分行的依次操作,操作次数取决于范围的容量

fetch--取得某行的操作权

fetch next--取得下一行的操作权

fetch_status--取得操作权的结果之状态返回值,0表示成功,非0表示失败,

例如达到了数据范围的结尾等均会导致失败

事务:一系列操作的集合,具有整体全部成功或全部失败的特点。必须同时具备ACID四大基本属性

A原子性(Atomicity)本系列操作的目标是完成独立的任务,所有操作内容为了本任务,不可以分割--复制文件中途取消

C一致性(Consistentency)在操作目标中,而偶们得到的结果与操作描述的结果必须保持一致,数据处理过程中不得有丢失或扭曲

I隔离性(Isolation)在多线程环境中,事务执行过程与其他事务执行过程相互分离的

D持久性(Durability)事务操作完毕之后,如果提交成功,则其产生的影响必须持久保持

 

隐形事务:常见的所有SQL语句均会导致自动生成隐形事务,以保证某一条语句的执行效果完整性。例如:insert into''''

显示事务:通过明确的关键语句代码,指定事务执行范围,在范围之内的一列写执行代码受到自定义事务的控制,

可以明确的对本事务的执行开始、保存、回滚、提交、验证等操作

begin transaction--启动事务,显示事务开始控制

rollback transaction--回滚事务,整个事务会抹除

commit transation --提交事务,确认本事务有效,并尝试保证其持久性

@@error--针对事务过程中的任何一条执行,监测器执行过程是否有误

 

*/

use MyDB

GO

 

--假设有两个由于历史原因造成的用户数据表需要归并,

create table UserInfoOne

(

    userid nvarchar(20) not null primary key,

    userpwd nvarchar(30) not null

)

go

create table UserInfoTwo

(

    userid nvarchar(20) not null primary key,

    userpwd nvarchar(30) not null

)

go

 

 

delete from UserInfoOne

delete from UserInfoTwo

go

 

insert into UserInfoOne(userid,userpwd) values ('mike','mike2122')

insert into UserInfoOne(userid,userpwd) values ('jie','jie2122')

insert into UserInfoOne(userid,userpwd) values ('hong','hong2122')

go

 

insert into UserInfoTwo(userid,userpwd) values ('mike','mike2122')

insert into UserInfoTwo(userid,userpwd) values ('xiao','xiao2122')

insert into UserInfoTwo(userid,userpwd) values ('yun','yun2122')

go

 

select * from UserInfoOne

select* from UserInfoTwo

go

 

/*

在存储过程或触发器中使用 Transact-SQL 游标的典型过程为:

 

声明 Transact-SQL 变量包含游标返回的数据。为每个结果集列声明一个变量。声明足够大的变量来保存列返回的值,并声明变量的类型为可从列数据类型隐式转换得到的数据类型。

 

 

使用 DECLARE CURSOR 语句将 Transact-SQL 游标与 SELECT 语句相关联。另外,DECLARE CURSOR 语句还定义游标的特性,例如游标名称以及游标是只读还是只进。

 

 

使用 OPEN 语句执行 SELECT 语句并填充游标。

 

 

使用 FETCH INTO 语句提取单个行,并将每列中的数据移至指定的变量中。然后,其他 Transact-SQL 语句可以引用那些变量来访问提取的数据值。Transact-SQL 游标不支持提取行块。

 

 

使用 CLOSE 语句结束游标的使用。关闭游标可以释放某些资源,例如游标结果集及其对当前行的锁定,但如果重新发出一个 OPEN 语句,则该游标结构仍可用于处理。由于游标仍然存在,此时还不能重新使用该游标的名称。DEALLOCATE 语句则完全释放分配给游标的资源,包括游标名称。释放游标后,必须使用 DECLARE 语句来重新生成游标。

*/

 

--假设操作目标:userinfotwo->userinfoone

--使用游标分行处理

begin

--声明游标

declare MoveUserInfoTwo cursor

for

select userid,userpwd from UserInfoTwo

--打开游标,准备开始读取操作

open MoveUserInfoTwo

--执行读取

declare @userid varchar(20) ,@userpwd nvarchar(30)

fetch next from MoveUseRInfoTwo into @userid,@userpwd

while(@@fetch_status=0)

 

    begin

    insert into   UserInfoOne(userid,userpwd) values(@userid,@userpwd)

    fetch next from MoveUserInfoTwo into @userid,@userpwd

    end

--完成游标操作,关闭游标

close MoveUserInfoTwo

--释放游标

deallocate MoveUserInfoTwo

end

go

 

--游标结合事务操作

begin transaction MoveUserInfoTrans

begin

declare @errorcount int

set @errorcount=0

--声明游标

declare MoveUserInfoTwo cursor

for

select userid, userpwd from UserInfoTwo

--打开游标

open MoveUserInfoTwo

--执行读取

declare @userid nvarchar(20),@userpwd nvarchar(30)

fetch next from MoveUserInfoTwo into @userid,@userpwd

while(@@fetch_status=0)

begin

insert into UserInfoOne(userid,userpwd) values(@userid,@userpwd)

if(@@error!=0)

begin

set @errorcount=@errorcount+1

break

end

fetch next from MoveUserInfoTwo into @userid,@userpwd

end

--完成游标操作关闭游标

close MoveUserInfoTwo

--释放游标

deallocate MoveUserInfoTwo

--验证本次事务的操作过程

if(@errorcount=0)

    begin

    commit transaction MoveUserInfoTrans

    print'事务提交成功'

    end

else

    begin

    rollback transaction MoveUserInfoTrans

    print'执行过程有误,事务已回滚'

    end

end

go

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值