sqlserver install

1。将Program files下的SQL安装目录删除(此处如果有重要的数据,请先备份)

C:\Program Files\Microsoft SQL Server\80\Tools。
C:\Program Files\Microsoft SQL Server\MSSQL。

2。注册表中的相关信息删除:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MSDTC。

3。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager中找到PendingFileRenameOperations项目,并删除它。这样就可以清除安装暂挂项目

 4。HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\setup
删除ExceptionComponents

   这个项目下的内容可能很多,只有在上面几个办法不行的情况下,使用此方法(注意不要全部删除)

删除内容前先看下内容说明

 5。Windows   目录中的   Sqlstp.log   文件,该文件列出了安装程序所执行的操作的详细信息,并包含安装期间遇到的所有错误。通过检查该文件,可以详细了解安装在什么地方失败、为什么失败。  


6。SQL安装的时的错误信息保存在一个叫Errorlog的日志文件中,默认情况下该文件位于   Program   Files\Microsoft   SQL   Server\Mssql\Log   目录中。该错误日志包含安装程序试图启动   SQL   Server   时   SQL   Server   所遇到的错误,这些信息可以帮助您深入检查错误原因。


7。需要检查的另一个组件是   Microsoft   数据访问组件   (MDAC)   安装程序,它作为   SQL   Server   2000   安装程序的一部分启动。SQL   Server   2000   安装程序会安装   MDAC   2.6。MDAC   安装程序会创建名为   Dasetup.log   的单独的日志文件;您可以查看此日志文件并确保   MDAC   安装程序没有出现问题。

 Visual Basic代码优化的六条军规
    在优化程序代码大小的诸多技术中,大多包括从代码中删除不必要的元素。在编译应用程序时,Visual Basic自动删除某些元素。而标识符名称、注释、空行的长度或数量是无须限制的,当应用程序作为一个。EXE文件运行时,以上这些元素都不会影响应用程序所占内存的大小。其他元素,如变量、窗体和过程,确实要占据内存的一部分空间。最好将它们精简以使效率更高。下面介绍6种方法可用于缩小应用程序所需内存和减少代码大小,希望能对初学者有所帮助。

  1、减少加载窗体、控件数目和用标签代替文本框

    每一个加载的窗体,无论可视与否,都要占据一定数量的内存(其数量随窗体上控件的类型和数量,以及窗体上位图的大小等的不同而变化)。只在需要显示时才加载窗体,不再需要时卸载窗体(而不是隐藏窗体)。记住,任何对窗体的属性、方法或控件的引用,或对用New声明的窗体变量的引用,都会导致Visual Basic加载该窗体。

    使用Unload方法卸载窗体时,只能释放部分窗体所占空间。要释放所有空间,可用关键字Nothing使窗体的引用无效:

    Set Form=Nothing

    当设计应用程序时,窗体应尽量少用控件。实际的限制取决于控件的类型和系统,但实际上,含有大量控件的窗体将运行缓慢。一项与之相关的技术是:设计时尽可能地使用控件数组,而不是在窗体上放置大量同类型的控件。控件数组是一组具有共同名称和类型的控件。它们的事件过程也相同。在设计时,使用控件数组添加控件所消耗的资源比直接向窗体添加多个相同类型的控件消耗的资源要少。当希望若干控件共享代码时,控件数组也很有用。标签控件Label占用的Windows资源比文本框Textbox少,因此在可能的情况下,应使用标签代替文本框。例如,当窗体上需要一个隐藏的控件保存文本时,使用标签更有效。

    2、使用磁盘文件或资源和组织模块

    在设计时,直接放入应用程序的数据(象属性或代码中的文字字符串和数值)将增加运行时应用程序占用的内存。运行时从磁盘文件或资源中加载数据可减少占用内存。这对大位图和字符串特别有价值。资源文件实际上是由一系列独立的字符串、位图或者其他项目组成的,其中每一项都有一个唯一的标识符。可以使用类似于在Microsoft Visual C++中提供的文本编辑器和资源编译器创建资源文件。编译过的资源文件带有。res扩展名。

    Visual Basic只在需要时才加载模块即当代码调用模块中的一个过程时,模块才被加载到内存。如果从未调用一特定模块中的过程,Visual Basic决不加载该模块。因此,尽量把相关的过程放在同一模块中,让Visual Basic只在需要时才加载模块。

    3、考虑替换Variant数据类型

    Variant数据类型使用极其灵活,但是比其他数据类型所占内存大。当要压缩应用程序多余的空间时,应考虑用其他数据类型替代Variant变量,特别是替代Variant变量数组。

    每一个Variant占用16个字节,而Integer占2个字节,Double占8个字节。变长字符串变量占用4个字节加上字符串中每一个字符占用1个字节,但是,每一个包含字符串的Variant都要占用16个字节加上字符串中每一个字符占用1个字节。因为它们太大,因此在用作局部变量或过程的参数时,Variant变量是特别烦人的,这是因为它们消耗堆栈空间太快。但在有些情况下,使用其他数据类型替代Variant,灵活性降低了,为弥补损失的灵活性,不得不增加更多的代码。结果是大小没有真正的减小。

   4、使用动态数组并在删除时回收内存

    使用动态数组代替固定数组。当不再需要动态数组的数据时,用Erase或ReDim Preserve放弃不需要的数据,并回收数组所用内存。例如,用以下代码可回收动态数组所用空间:

[Blocked Ads]

    Erase MyArray

    里,Erase完全删除数组,ReDim Preserve则只缩短数组而不丢失其内容:

    ReDim Preserve MyArray(10, smallernum)

    删除了固定大小数组,也不能回收该数组所占空间——只是简单地清除数组每一元素中的值。如果元素是字符串,或包含字符串或数组的Variant变量,那么删除数组可回收这些字符串或Variants所占内存,而不是数组本身所占内存。

    5、回收被字符串或对象变量用过的空间

    当过程结束时,可自动回收(非静态)局部字符串和数组变量所用空间。但是,全局和模块级的字符串和数组变量一直存活到整个程序结束。要想应用程序尽量小,就得尽可能回收这些变量所用空间。将零长度字符串赋给字符串变量,可回收其空间:

    SomeString Var="" '回收空间

    同样,将对象变量设置成Nothing可回收该对象所用的部分(而不是全部)空间。例如,删除一个Form对象变量:

    Global F As New StatusForm F.Show 1 'Form加载并以模态显示X=F.Text1.Text '用户按下按钮,隐藏窗体Unload F '删除窗体可视部分Set F=Nothing '回收空间(模块数据)

    即使没有使用显式窗体变量,也应注意将不再用的窗体卸载,而不是简单地隐藏。

    6、消除死代码和无用的变量

    在开发和修改应用程序时,可能遗留了死代码——代码中的一个完整过程,而它并没有被任何地方调用。也可能声明了一些不用的变量。虽然在创建。exe文件中,Visual Basic确实可删除无用的常数,但不能删除无用的变量和死代码。注意要复查代码,查找并删除无用的变量和死代码。如Debug.Print语句,在运行。exe时被忽略,可它常常出现在。exe文件中。

    当创建。exe文件时,含有字符串和变量作为参数的Debug.Print语句不会被编译。但对于含有函数作为参数的Debug.Print语句,其本身被编译器忽略,而函数则被编译。因此,在应用程序运行时,函数被调用,但返回值被忽略。因为在。exe文件中,函数作为Debug.Print的参数出现时,将占用空间和CPU周期时间,所以在生成exe文件前,最好删除这些语句。

    在"编辑"菜单中使用"查找"命令搜索特定变量的引用。或者当每个模块都含有Option Explicit语句时,通过删除或注释该变量的声明,并运行应用程序,可迅速发现变量是否被使用。若该变量被使用,则Visual Basic将出错。若不出错,则该变量没被使用。

SQL Server 数据库管理常用的SQL和T-SQL

1. 查看数据库的版本  
  select @@version
 
2. 查看数据库所在机器操作系统参数  
  exec master..xp_msver
 
3. 查看数据库启动的参数        
  sp_configure
       
4. 查看数据库启动时间        
  select convert(varchar(30),login_time,120) from master..sysprocesses where spid=1
 
  查看数据库服务器名和实例名
  print 'Server Name...............: ' + convert(varchar(30),@@SERVERNAME)        
  print 'Instance..................: ' + convert(varchar(30),@@SERVICENAME)      

5. 查看所有数据库名称及大小
  sp_helpdb
 
  重命名数据库用的SQL
  sp_renamedb 'old_dbname', 'new_dbname'
 
6. 查看所有数据库用户登录信息
  sp_helplogins
 
  查看所有数据库用户所属的角色信息  
  sp_helpsrvrolemember
 
  修复迁移服务器时孤立用户时,可以用的fix_orphan_user脚本或者LoneUser过程
 
  更改某个数据对象的用户属主
  sp_changeobjectowner [@objectname =] 'object', [@newowner =] 'owner'
 
  注意: 更改对象名的任一部分都可能破坏脚本和存储过程。
 
  把一台服务器上的数据库用户登录信息备份出来可以用add_login_to_aserver脚本
 
7. 查看链接服务器      
  sp_helplinkedsrvlogin
 
  查看远端数据库用户登录信息  
  sp_helpremotelogin
 
8.查看某数据库下某个数据对象的大小
  sp_spaceused @objname
 
  还可以用sp_toptables过程看最大的N(默认为50)个表
 
  查看某数据库下某个数据对象的索引信息
  sp_helpindex @objname
 
  还可以用SP_NChelpindex过程查看更详细的索引情况
  SP_NChelpindex @objname
 
  clustered索引是把记录按物理顺序排列的,索引占的空间比较少。
  对键值DML操作十分频繁的表我建议用非clustered索引和约束,fillfactor参数都用默认值。

  查看某数据库下某个数据对象的的约束信息
  sp_helpconstraint @objname
 
9.查看数据库里所有的存储过程和函数
  use @database_name
  sp_stored_procedures

  查看存储过程和函数的源代码
  sp_helptext '@procedure_name'
 
  查看包含某个字符串@str的数据对象名称
  select distinct object_name(id) from syscomments where text like '%@str%'
 
  创建加密的存储过程或函数在AS前面加WITH ENCRYPTION参数
 
  解密加密过的存储过程和函数可以用sp_decrypt过程
 
      10.查看数据库里用户和进程的信息
  sp_who

  查看SQL Server数据库里的活动用户和进程的信息
  sp_who 'active'

  查看SQL Server数据库里的锁的情况
  sp_lock
 
  进程号1--50是SQL Server系统内部用的,进程号大于50的才是用户的连接进程.

  spid是进程编号,dbid是数据库编号,objid是数据对象编号

  查看进程正在执行的SQL语句
  dbcc inputbuffer ()
       
  推荐大家用经过改进后的sp_who3过程可以直接看到进程运行的SQL语句
  sp_who3
 
  检查死锁用sp_who_lock过程
  sp_who_lock  
   
      11.收缩数据库日志文件的方法

  收缩简单恢复模式数据库日志,收缩后@database_name_log的大小单位为M
  backup log @database_name with no_log
  dbcc shrinkfile (@database_name_log, 5)

      12.分析SQL Server SQL 语句的方法:
     
  set statistics time {on | off}

  set statistics io {on | off}

          图形方式显示查询执行计划
         
          在查询分析器->查询->显示估计的评估计划(D)-Ctrl-L 或者点击工具栏里的图形
         
          文本方式显示查询执行计划

  set showplan_all {on | off}
 
  set showplan_text { on | off }

  set statistics profile { on | off }
 

      13.出现不一致错误时,NT事件查看器里出3624号错误,修复数据库的方法
 
  先注释掉应用程序里引用的出现不一致性错误的表,然后在备份或其它机器上先恢复然后做修复操作
 
  alter database [@error_database_name] set single_user
 
  修复出现不一致错误的表
 
  dbcc checktable('@error_table_name',repair_allow_data_loss)
 
  或者可惜选择修复出现不一致错误的小型数据库名
 
  dbcc checkdb('@error_database_name',repair_allow_data_loss)

  alter database [@error_database_name] set multi_user

  CHECKDB 有3个参数:

  repair_allow_data_loss 包括对行和页进行分配和取消分配以改正分配错误、结构行或页的错误,
  以及删除已损坏的文本对象,这些修复可能会导致一些数据丢失。
  修复操作可以在用户事务下完成以允许用户回滚所做的更改。
  如果回滚修复,则数据库仍会含有错误,应该从备份进行恢复。
  如果由于所提供修复等级的缘故遗漏某个错误的修复,则将遗漏任何取决于该修复的修复。
  修复完成后,请备份数据库。

  repair_fast 进行小的、不耗时的修复操作,如修复非聚集索引中的附加键。
  这些修复可以很快完成,并且不会有丢失数据的危险。

  repair_rebuild 执行由 repair_fast 完成的所有修复,包括需要较长时间的修复(如重建索引)。
  执行这些修复时不会有丢失数据的危险。

1.按姓氏笔画排序:
Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as

2.数据库加密:
select encrypt('原始密码')
select pwdencrypt('原始密码')
select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同 encrypt('原始密码')
select pwdencrypt('原始密码')
select pwdcompare('原始密码','加密后密码') = 1--相同;否则不相同

3.取回表中字段:
declare @list varchar(1000),@sql nvarchar(1000)
select @list=@list+','+b.name from sysobjects a,syscolumns b where a.id=b.id and a.name='表A'
set @sql='select '+right(@list,len(@list)-1)+' from 表A'
exec (@sql)

4.查看硬盘分区:
EXEC master..xp_fixeddrives

5.比较A,B表是否相等:
if (select checksum_agg(binary_checksum(*)) from A)
    =
   (select checksum_agg(binary_checksum(*)) from B)
print '相等'
else
print '不相等'

6.杀掉所有的事件探察器进程:
DECLARE hcforeach CURSOR GLOBAL FOR SELECT 'kill '+RTRIM(spid) FROM master.dbo.sysprocesses
WHERE program_name IN('SQL profiler',N'SQL 事件探查器')
EXEC sp_msforeach_worker '?'

7.记录搜索:
开头到N条记录
Select Top N * From 表
-------------------------------
N到M条记录(要有主索引ID)
Select Top M-N * From 表 Where ID in (Select Top M ID From 表) Order by ID  Desc
----------------------------------
N到结尾记录
Select Top N * From 表 Order by ID Desc

8.如何修改数据库的名称:
sp_renamedb 'old_name', 'new_name'

9:获取当前数据库中的所有用户表
select Name from sysobjects where xtype='u' and status>=0

10:获取某一个表的所有字段
select name from syscolumns where id=object_id('表名')

11:查看与某一个表相关的视图、存储过程、函数
select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%表名%'

12:查看当前数据库中所有存储过程
select name as 存储过程名称 from sysobjects where xtype='P'

13:查询用户创建的所有数据库
select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name='sa')
或者
select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0x01

14:查询某一个表的字段和数据类型
select column_name,data_type from information_schema.columns
where table_name = '表名'

[n].[标题]:
Select * From TableName Order By CustomerName

[n].[标题]:
Select * From TableName Order By CustomerName
--SQL Server的存储过程调用Com组件
 

/*--下面的部分在VB中完成
 
首先我们先用VB 作一个最简单的组件
 
工程名称: testSQLCOM
类名: TestMath
 
'函数,计算两个整数相加的结果
Public Function AddMe(a As Long, b As Long) As Long
   AddMe = a + b
End Function
 
编译生成后,我们就可以在 Sql Server 中对这个 Com 组件进行调用了
--*/
 
/*--下面是SQL中对上面DLL的调用--*/
 
--定义用到的变量
declare @err int,@src varchar(255),@desc varchar(255)
declare @obj int,@re int
 
--创建调用实例
exec @err=sp_OACreate 'testSQLCOM.TestMath', @obj out
if @err<>0 goto lberr  --如果创建失败,则进行错误处理
 
--调用DLL中的函数
exec @err=sp_OAMethod @obj,'AddMe',@re out,100,200
if @err<>0 goto lberr  --如果调用错误,则进行错误处理
 
print '返回的结果是:' + str(@re)
 
--完成后释放
exec sp_OADestroy @obj
 
return
 
lberr:
 exec sp_oageterrorinfo 0,@src out,@desc out
 select cast(@err as varbinary(4)) as 错误号
  ,@src as 错误源,@desc as 错误描述

/*--处理死锁

 查看当前进程,或死锁进程,并能自动杀掉死进程

 因为是针对死的,所以如果有死锁进程,只能查看死锁进程
 当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程

--邹建 2004.4--*/

/*--调用示例

 exec p_lockinfo
--*/
create proc p_lockinfo
@kill_lock_spid bit=1,  --是否杀掉死锁的进程,1 杀掉, 0 仅显示
@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示
as
declare @count int,@s nvarchar(1000),@i int
select id=identity(int,1,1),标志,
 进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
 数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,
 登陆时间=login_time,打开事务数=open_tran, 进程状态=status,
 工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,
 域名=nt_domain,网卡地址=net_address
into #t from(
 select 标志='死锁的进程',
  spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
  status,hostname,program_name,hostprocess,nt_domain,net_address,
  s1=a.spid,s2=0
 from master..sysprocesses a join (
  select blocked from master..sysprocesses group by blocked
  )b on a.spid=b.blocked where a.blocked=0
 union all
 select '|_牺牲品_>',
  spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
  status,hostname,program_name,hostprocess,nt_domain,net_address,
  s1=blocked,s2=1
 from master..sysprocesses a where blocked<>0
)a order by s1,s2

select @count=@@rowcount,@i=1

if @count=0 and @show_spid_if_nolock=1
begin
 insert #t
 select 标志='正常的进程',
  spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
  open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address
 from master..sysprocesses
 set @count=@@rowcount
end

if @count>0
begin
 create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))
 if @kill_lock_spid=1
 begin
  declare @spid varchar(10),@标志 varchar(10)
  while @i<=@count
  begin
   select @spid=进程ID,@标志=标志 from #t where id=@i
   insert #t1 exec('dbcc inputbuffer('+@spid+')')
   if @标志='死锁的进程' exec('kill '+@spid)
   set @i=@i+1
  end
 end
 else
  while @i<=@count
  begin
   select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i
   insert #t1 exec(@s)
   set @i=@i+1
  end
 select a.*,进程的SQL语句=b.EventInfo
 from #t a join #t1 b on a.id=b.id
end
go

如何不通过其他工具,把图片、声音等存储到sql中

用image类型

方法:
1、建立过程
CREATE PROCEDURE sp_textcopy (
  @srvname    varchar (30),
  @login      varchar (30),
  @password    varchar (30),
  @dbname      varchar (30),
  @tbname      varchar (30),
  @colname    varchar (30),
  @filename    varchar (30),
  @whereclause varchar (40),
  @direction  char(1))
AS
DECLARE @exec_str varchar (255)
SELECT @exec_str =
        'textcopy /S ' + @srvname +
        ' /U ' + @login +
        ' /P ' + @password +
        ' /D ' + @dbname +
        ' /T ' + @tbname +
        ' /C ' + @colname +
        ' /W "' + @whereclause +
        '" /F ' + @filename +
        ' /' + @direction
EXEC master..xp_cmdshell @exec_str 

2、建表和初始化数据
create table 表名 (编号 int,image列名 image)
go
insert 表名 values(1,0x)    -- 必须的,且不是null
insert 表名 values(2,0x)    -- 必须的,且不是null
go

3、读入
sp_textcopy '你的服务器名','sa','你的密码','库名','表名','image列名','c:\图片.bmp','where 编号=1','I' --注意条件是 编号=1

sp_textcopy '你的服务器名','sa','你的密码','库名','表名','image列名','c:\bb.doc','where 编号=2','I' --注意条件是 编号=2

go

4、读出成文件
sp_textcopy '你的服务器名','sa','你的密码','库名','表名','image列名','c:\图片.bmp','where 编号=1','O' --注意条件是 编号=1

sp_textcopy '你的服务器名','sa','你的密码','库名','表名','image列名','c:\bb.doc','where 编号=2','O' --注意条件是 编号=2
go

如果报textcopy不是可执行文件的话,你就到
C:\Program Files\Microsoft SQL Server\MSSQL\Binn
目录下拷备 textcopy.exe到:
C:\Program Files\Microsoft SQL Server\80\Tools\Binn

全文索引——CONTAINS 语法
我们通常在 WHERE 子句中使用 CONTAINS ,就象这样:SELECT * FROM table_name WHERE CONTAINS(fullText_column,'search contents')。

我们通过例子来学习,假设有表 students,其中的 address 是全文本检索的列。
1. 查询住址在北京的学生
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'beijing' )
remark: beijing是一个单词,要用单引号括起来。

2. 查询住址在河北省的学生
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"HEIBEI province"' )
remark: HEBEI province是一个词组,在单引号里还要用双引号括起来。

3. 查询住址在河北省或北京的学生
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"HEIBEI province" OR beijing' )
remark: 可以指定逻辑操作符(包括 AND ,AND NOT,OR )。

4. 查询有 '南京路' 字样的地址
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'nanjing NEAR road' )
remark: 上面的查询将返回包含 'nanjing road','nanjing east road','nanjing west road' 等字样的地址。
          A NEAR B,就表示条件: A 靠近 B。

5. 查询以 '湖' 开头的地址
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"hu*"' )
remark: 上面的查询将返回包含 'hubei','hunan' 等字样的地址。
          记住是 *,不是 %。

6. 类似加权的查询
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'ISABOUT (city weight (.8), county wright (.4))' )
remark: ISABOUT 是这种查询的关键字,weight 指定了一个介于 0~1之间的数,类似系数(我的理解)。表示不同条件有不同的侧重。

7. 单词的多态查询
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'FORMSOF (INFLECTIONAL,street)' )
remark: 查询将返回包含 'street','streets'等字样的地址。
         对于动词将返回它的不同的时态,如:dry,将返回 dry,dried,drying 等等。

以上例子都使用英文,不使用中文是因为有的查询方式中文不支持,而且我的计算机是英文系统。
sql server的cube操作符使用详解
cube操作符
   要使用cube,首先要了解group by
   其实cube和rollup区别不太大,只是在基于group by 子句创建和汇总分组的可能的组合上有一定差别,
   cube将返回的更多的可能组合。如果在 group by 子句中有n个列或者是有n个表达式的话,
   sqlserver在结果集上会返回2的n-1次幂个可能组合。
 注意:
   使用cube操作符时,最多可以有10个分组表达式
   在cube中不能使用all关键字
 例子:
   我们在数据库统计中常常要查询以下情况:
   如一个定单数据库,我们要知道每个定单的每个产品数量,每个定单的所有产品数量,所有定单的某一产品数量,所有定单所有产品总量这些汇总信息。这时使用cube就十分方便了。当然不需要这么多信息或者只想知道某一具体产品、具体某一定单,某一时间关系(前,后,之间)等等具体信息的话,只需在where中限定即可
   先举一个例子,是所有情况的:
   一个数据库表中记载了一个产品定购情况:
   现共有三种产品(1,2,3),已经下了两个定单(1,2)
   sql语句:
   select productid,orderid SUM(quantity) AS total FROM order GROUP BY productid,orderid WITH CUBE
     ORDER BY productid,orderid
   运行后得到结果:
   productid   orderid   total
   null          null     95                      所有定单所有产品总量
   null           1       30                      定单1所有产品数量
   null           2       65                      定单2所有产品数量
   1             null     15                      所有定单产品1总量
   1              1        5                      定单1产品1数量
   1              2       10                      定单2产品1数量
   2             null     35                      所有定单产品2总量
   2              1       10                      定单1产品2数量
   2              2       25                      定单2产品2数量 
   3             null     45                      所有定单产品3总量   
   3              1       15                      定单1产品3数量
   3              2       30                      定单2产品3数量

   如果您对sqlserver  group by  聚集有一定理解的话,您就可以理解cube操作符的用法和作用。其实在现实运用中cube还是很好有的,我们经常要对一些数据库数据进行统计,以利于我们更好的掌握情况
   我想电子商务可以更好的实现合理配置资源,尽量减少库存,只有更好的掌握生产、销售数据的具体情况,才能实现资源的合理配置。希望以后的企业象dell一样,不要象长虹等彩电厂商。


join 使用详解方式
 join 方式
(1) cross join
      参与select语句所有表的的所有行的笛卡尔乘积
      select au_lname ,title from authors cross join  titiles
      outer join 对参与join的两个表有主从之分,处理方式以主表的每条数据去match 从属表的列,合乎条件的数据是我们所要的答案,不合乎条件的也是我们要的答案,只不过哪些从属表选取的列将被添上null。
(2) left join
     左边的为主表,右边为从属表
     select a.cust_id ,b.order_date,b.tot_ant from customer a left join sales b
       on (a.cust_id =b.cust_id and b.order_date>''1996/10/15'')
     可以写为
     select a.cust_id,b.order_date,b.tot_ant from custom a
        left join (select * from sales where order_date>''1996/10/15'') b
        on a.cust_id =b.cust_id  
(3) right join
     左边的表为从属表,右边的表为主表
(4) self join
     self join 常用在同一表内不同数据间对同一列的比较
     select a.emp_no,a.emp_name,b.emp_no,b.emp_name,a.date_hired from employee a
        join employee b on (a.emp_no!=b.emp_no and a.date_hired=b.date_hired)
            order by a.date_hired
     这样会重复数据,只要加上一句 and a.emp_name>b.emp_name
(5) full join
     不仅列出符合条件的数据,两边未符合join条件的数据也会一并列出。哪些未符合join条件的数据如果在select列中无法得到对应的值则填上null
    select a.cust_id,b.tot_amt from customer a full join sales b
         on a.cust_id=b.cust_id
    有表
     id   ic  name  amount
      I    *        *
      c
      i
      c
      i
      i  
   要求结果为 
    ic  name  amount  ic   name  amount
    i                         c
    i                         c
    i
    i
  select aaa.*,bbb.*  from (select (select count(id) from aa as b where (b.id<a.id) and (ic=''i'')) as newid, *
        from aa a where ic=''i'') aaa full join
         (select (select count(id) from aa as b where b.id<a.id and ic=''c'') as newid,* from
             aa a where ic=''c'') bbb on aaa.newid=bbb.newid order by aaa.name 
 6.使用 HASH 和 MERGE 联接提示
   此示例在 authors、titleauthors 和 titles 表之间建立三表联接,以生成一个作者及其著作的列表。查询优化器使用 MERGE 联接将 authors 和 titleauthors (A x TA) 联接在一起。然后,将 authors 和 titleauthors MERGE 联接 (A x TA) 的结果与 titles 表进行 HASH 联结以生成 (A x TA) x T。
 重要  指定联接提示后,要执行 INNER JOIN 时 INNER 关键字不再为可选,而必须显式说明。
  USE pubs
  SELECT SUBSTRING((RTRIM(a.au_fname) + '' '' + LTRIM(a.au_lname)), 1, 25)
     AS Name, SUBSTRING(t.title, 1, 20) AS Title
     FROM authors a INNER MERGE JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER HASH JOIN titles t
      ON t.title_id = ta.title_id
     ORDER BY au_lname ASC, au_fname ASC

  下面是结果集:

  Warning: The join order has been enforced because a local join hint is used.
  Name                      Title               
  ------------------------- --------------------
  Abraham Bennet            The Busy Executive''s
  Reginald Blotchet-Halls   Fifty Years in Bucki
  Cheryl Carson             But Is It User Frien
  Michel DeFrance           The Gourmet Microwav
  Innes del Castillo        Silicon Valley Gastr
  ...                    ...
  Johnson White             Prolonged Data Depri
  Akiko Yokomoto            Sushi, Anyone?      

  (25 row(s) affected)

使用约束
1.使用 primary key 约束
  其值能唯一的标识表中的每一行。这样的一列或多列成为表的主键,通过它可强制表的实体完整性。
  job_id int primary key clustered
  emp_id empid constraint pk_emp_id primary key nonclustered
2.使用foreign key 约束
   约束引用其他的表
  job_id samllint not null  references jobs(job_id)
  foreign key(job_id) references jobs(job_id)
  constraint fk_sales foreign key(stor_id,orde_num,title_id)
  references sales(stor_id,ord_num,title_id)
3.使用unique 约束
  unqiue约束用于强制非主键列的唯一性,允许存在空值(应该只有一个)
  person varchar(30) null unique nonclustered
  constraint u_store unique nonclustered(stor_name,city)
4.使用default定义
  使用insert和update语句时,如果没有提供值,则使用默认值。
  提供了默认值,  用dbgrid 编辑必须在onnewrecord 事件加上默认值的赋值,否则提示错误
 ‘row can not be located for updating.some values has been changed since it was last read ' 
  default(getdate())
  创建一个产品价格表,并且设置产品的改价者为当时增修改数据的用户
  create table price
  (
   prod_id char(5),
   sup_id   char(5),
   unit_price money,
   modifier char(5)
   modi_date datetime default getdate(),
   primary key(prod_id,sup_id)
   default user for modifier
   )
5.使用check约束
  check(min_lvl>=10) 
  check(max_lvl<=250)
  constraint ck_emp_id check (emp_id like '[a-z][a-z][a-z][1-9][0-9][0-9][0-9][0-9]'
      or emp_id like [a-z][a-z][1-9][0-9][0-9][0-9][0-9]')
  check (pub_id in ('1389','0736','0877') or pub_id like'99[0-9][0-9]'
存储过程编写经验和优化措施

介绍:在数据库的开发过程中,经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。如果项目的SP较多,书写又没有一定的规范,将会影响以后的系统维护困难和大SP逻辑的难以理解,另外如果数据库的数据量大或者项目对SP的性能要求很,就会遇到优化的问题,否则速度有可能很慢,经过亲身经验,一个经过优化过的SP要比一个性能差的SP的效率甚至高几百倍。

内容:

1、开发人员如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用“databse.dbo.table_name”,因为sp_depends不能显示出该SP所使用的跨库table或view,不方便校验。

2、开发人员在提交SP前,必须已经使用set showplan on分析过查询计划,做过自身的查询优化检查。

3、高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点:

a)        SQL的使用规范:

i.  尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。
ii. 尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。
iii.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。
iv. 注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。
v.  不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
vi. 尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。
vii.尽量使用“>=”,不要使用“>”。
viii.注意一些or子句和union子句之间的替换
ix.注意表之间连接的数据类型,避免不同类型数据之间的连接。
x. 注意存储过程中参数和数据类型的关系。
xi.注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400k),那么系统将会进行锁升级,页级锁会升级成表级锁。


b) 索引的使用规范:
i.  索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。
ii. 尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引
iii.避免对大表查询时进行table scan,必要时考虑新建索引。
iv. 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。
v.  要注意索引的维护,周期性重建索引,重新编译存储过程。


c)tempdb的使用规范:
i.  尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。
ii. 避免频繁创建和删除临时表,减少系统表资源的消耗。
iii.在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。
iv. 如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。
v.  如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。
vi. 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

d)合理的算法使用:
根据上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,结合实际应用,采用多种算法进行比较,以获得消耗资源最少、效率最高的方法。具体可用ASE调优命令:set statistics io on, set statistics time on , set showplan on 等。

********* 利用数据库复制技术 实现数据同步更新 *********

复制的概念

Microsoft? SQL Server? 2000 的复制是在数据库之间对数据和数据库对象进行复制
和分发并进行同步以确保其一致性的一组技术。

使用复制可以将数据分发到不同位置,通过局域网、使用拨号连接、通过 Internet 分
发给远程或移动用户。复制还能够使用户提高应用程序性能,根据数据的使用方式物理
分隔数据(例如,将联机事务处理 (OLTP) 和决策支持系统分开),或者跨越多个服务
器分布数据库处理。

---------------------------------------------------------------------------
SQL复制的基本元素包括

发布服务器、订阅服务器、分发服务器、发布、项目

发布服务器
发布服务器是提供数据以便复制到其它服务器的服务器。发布服务器可以具有一个或多个
发布,每个发布代表一组逻辑相关的数据。除了指定其中哪些数据需要复制之外,发布服
务器还检测事务复制期间发生更改的数据并维护有关此站点上所有发布的信息。
分发服务器
分发服务器是作为分发数据库宿主并存储历史数据和/或事务以及元数据的服务器。分发
服务器的角色根据执行的复制类型而不同。有关更多信息,请参见复制类型。
远程分发服务器是独立于发布服务器并配置为复制的分发服务器的服务器。本地分发服务
器是既配置为复制的发布服务器又配置为复制的分发服务器的服务器。
订阅服务器
订阅服务器是接收复制数据的服务器。订阅服务器订阅的是发布而不是发布中分离的项目;
并且订阅服务器只订阅其需要的发布,而不是发布服务器上所有可用的发布。根据复制的类
型和所选择的复制选项,订阅服务器还可以将数据更改传播回发布服务器或将数据重新发布
到其它订阅服务器。
发布
发布是一个数据库中的一个或多个项目的集合。这种多个项目的分组使得指定逻辑相关的一
组数据和数据库对象以一起复制变得更容易。
项目
项目是指定要复制的数据表、数据分区或数据库对象。项目可以是完整的表、某几列(使用垂
直筛选)、某几行(使用水平筛选)、存储过程或视图定义、存储过程的执行、视图、索引视图
或用户定义函数。
订阅
订阅是对数据或数据库对象的复本的请求。订阅定义将接收的发布和接收的时间、地点。订阅的
同步或数据分发可以由发布服务器(强制订阅)或订阅服务器(请求订阅)请求。发布可以支持
强制订阅和请求订阅的混合。
---------------------------------------------------------------------------
SQL复制的工作原理
SQL SERVER 主要采用出版物、订阅的方式来处理复制。源数据所在的服务器是出版服务
器,负责发表数据。出版服务器把要发表的数据的所有改变情况的拷贝复制到分发服务器
分发服务器包含有一个分发数据库,可接收数据的所有改变,并保存这些改变,再把这些
改变分发给订阅服务器

---------------------------------------------------------------------------
SQL SERVER复制技术类型,三种复制技术,分别是(详细的说明参考SQL联机帮助):
1、快照复制
2、事务复制
3、合并复制

============================================================================
下介绍实现复制的步骤。(以快照复制为例)

准备工作:

1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户
--我的电脑
--控制面板
--管理工具
--计算机管理
--用户和组
--右键用户
--新建用户
--建立一个隶属于administrator组的登陆windows的用户

2.在发布服务器上,新建一个共享目录,做为发布的快照文件的存放目录,操作:

我的电脑--D:\ 新建一个目录,名为: PUB
--右键这个新建的目录
--属性--共享
--选择"共享该文件夹"
--通过"权限"按纽来设置具体的用户权限,保证第一步中创建的用户具有对该文件夹的所有权限
--确定


3.设置SQL代理(SQLSERVERAGENT)服务的启动用户(发布/订阅服务器均做此设置)

开始--程序--管理工具--服务
--右键SQLSERVERAGENT
--属性--登陆--选择"此账户"
--输入或者选择第一步中创建的windows登录用户名
--"密码"中输入该用户的密码

4.设置SQL Server身份验证模式,解决连接时的权限问题(发布/订阅服务器均做此设置)

企业管理器
--右键SQL实例--属性
--安全性--身份验证
--选择"SQL Server 和 Windows"
--确定

5.在发布服务器和订阅服务器上互相注册
企业管理器
--右键SQL Server组
--新建SQL Server注册...
--下一步--可用的服务器中,输入你要注册的远程服务器名--添加
--下一步--连接使用,选择第二个"SQL Server身份验证"
--下一步--输入用户名和密码
--下一步--选择SQL Server组,也可以创建一个新组
--下一步--完成

6.对于只能用IP,不能用计算机名的,为其注册服务器别名
  (在连接端配置,比如,在订阅服务器上配置的话,服务器名称中输入的是发布服务器的IP)
开始--程序--Microsoft SQL Server--客户端网络实用工具
--别名--添加
--网络库选择"tcp/ip"--服务器别名输入SQL服务器名
--连接参数--服务器名称中输入SQL服务器ip地址
--如果你修改了SQL的端口,取消选择"动态决定端口",并输入对应的端口号

==============================================================================

正式开始:

1.配置发布服务器

a. 选中指定 [服务器] 节点
b. 从 [工具] 下拉菜单的 [复制] 子菜单中选择 [发布、订阅服务器和分发] 命令
c. 系统弹出一个对话框点 [下一步] 然后看着提示操作
--直到"指定快照文件夹"
--在"快照文件夹"中输入准备工作中创建的目录: \\<服务器名>\pub
一[下一步] 直操作到完成。
d. 当完成了出版服务器的设置以后系统会为该服务器的树形结构中添加一个复制监视器
同时也生成一个分发数据库(distribution)


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

2.创建发布
a. 选中指定的服务器
b. 从 [工具] 菜单的 [复制] 子菜单中选择 [创建和管理发布] 命令。此时系统会弹出
一个对话框
c. 选择要创建发布的数据库,然后单击 [创建发布]
d. 在 [创建发布向导] 的提示对话框中单击 [下一步] 系统就会弹出一个对话框。对话
框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个
大家可以去看看帮助)
e. 单击 [下一步] 系统要求指定可以订阅该发布的数据库服务器类型,SQLSERVER允许在
不同的数据库如 ORACLE或ACCESS之间进行数据复制。但是在这里我们选择运行
"SQL SERVER 2000"的数据库服务器
f. 单击 [下一步] ,选择要发布的对象(如表,视图,存储过程,一般是表)
g. 然后 [下一步] 直到操作完成。当完成出版物的创建后创建出版物的数据库也就变成了
一个共享数据库。


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

3.设计订阅
a. 选中指定的订阅服务器
b. 从 [工具] 下拉菜单中选择 [复制] 子菜单的 [请求订阅]
c. 按照提示单击 [下一步] 操作直到系统会提示检查SQL SERVER代理服务的运行状态,执行
复制操作的前提条件是SQL SERVER代理服务必须已经启动。
d. 单击 [完成] 完成订阅操作。


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

完成上面的步骤其实复制也就是成功了。但是如何来知道复制是否成功了呢?
这里可以通过这种方法来快速看是否成功。
展开出版服务器下面的复制——发布内容——右键发布内容——属性——击活——状态然后点立即运行代理程序接着点代理程序属性击活调度
把调度设置为每一天发生,每一分钟,在0:00:00和23:59:59之间。
接下来就是判断复制是否成功了打
开C:\Program Files\Microsoft SQL Server\MSSQL\REPLDATA\unc\XIAOWANGZI_database_database下面
看是不是有一些以时间做为文件名的文件夹差不多一分中就产生一个。

DECLARE @DatabaseRoleName [sysname]
SET @DatabaseRoleName = 'createrole'            --角色名

SET NOCOUNT ON
DECLARE
@errStatement [varchar](8000),
@msgStatement [varchar](8000),
@DatabaseRoleID [smallint],
@IsApplicationRole [bit],
@ObjectID [int],
@ObjectName [sysname]

SELECT
@DatabaseRoleID = [uid],
@IsApplicationRole = CAST([isapprole] AS bit)
FROM [dbo].[sysusers]
WHERE
[name] = @DatabaseRoleName
AND
(
[issqlrole] = 1
OR [isapprole] = 1
)
AND [name] NOT IN
(
'public',
'INFORMATION_SCHEMA',
'db_owner',
'db_accessadmin',
'db_securityadmin',
'db_ddladmin',
'db_backupoperator',
'db_datareader',
'db_datawriter',
'db_denydatareader',
'db_denydatawriter'
)

IF @DatabaseRoleID IS NULL
BEGIN
IF @DatabaseRoleName IN
(
'public',
'INFORMATION_SCHEMA',
'db_owner',
'db_accessadmin',
'db_securityadmin',
'db_ddladmin',
'db_backupoperator',
'db_datareader',
'db_datawriter',
'db_denydatareader',
'db_denydatawriter'
)
SET @errStatement = 'Role ' + @DatabaseRoleName + ' is a fixed database role and cannot be scripted.'
ELSE
SET @errStatement = 'Role ' + @DatabaseRoleName + ' does not exist in ' + DB_NAME() + '.' + CHAR(13) +
'Please provide the name of a current role in ' + DB_NAME() + ' you wish to script.'

RAISERROR(@errStatement, 16, 1)
END
ELSE
BEGIN
SET @msgStatement = '--Security creation script for role ' + @DatabaseRoleName + CHAR(13) +
'--Created At: ' + CONVERT(varchar, GETDATE(), 112) + REPLACE(CONVERT(varchar, GETDATE(), 108), ':', '') + CHAR(13) +
'--Created By: ' + 'Ldyia ' + CHAR(13) +
'--Add Role To Database' + CHAR(13)
IF @IsApplicationRole = 1
SET @msgStatement = @msgStatement + 'EXEC sp_addapprole' + CHAR(13) +
CHAR(9) + '@rolename = ''' + @DatabaseRoleName + '''' + CHAR(13) +
CHAR(9) + '@password = ''{Please provide the password here}''' + CHAR(13)
ELSE
BEGIN
SET @msgStatement = @msgStatement + 'EXEC sp_addrole' + CHAR(13) +
CHAR(9) + '@rolename ''' + @DatabaseRoleName + '''' + CHAR(13)
PRINT 'GO'
END
SET @msgStatement = @msgStatement + '--Set Object Specific Permissions For Role'
PRINT @msgStatement

SELECT
DISTINCT([sysobjects].[id]),
'[' + USER_NAME([sysobjects].[uid]) + '].[' + [sysobjects].[name] + ']' as 'Object'
INTO #
FROM [dbo].[sysprotects]
LEFT JOIN [dbo].[sysobjects]
ON [sysprotects].[id] = [sysobjects].[id]
WHERE [sysobjects].[id] is not null
      AND [sysprotects].[uid] = @DatabaseRoleID

INSERT # SELECT 0,@DatabaseRoleName

DECLARE _sysobjects
CURSOR
LOCAL
FORWARD_ONLY
READ_ONLY
FOR
SELECT * FROM #

OPEN _sysobjects
FETCH
NEXT
FROM _sysobjects
INTO
@ObjectID,
@ObjectName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @msgStatement = ''
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 193 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'SELECT,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 195 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'INSERT,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 197 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'UPDATE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 196 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'DELETE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 224 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'EXECUTE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 26 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'REFERENCES,'

IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 198 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE TABLE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 203 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE DATABASE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 207 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE VIEW,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 222 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE PROCEDURE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 224 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'EXECUTE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 228 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'BACKUP DATABASE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 233 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE DEFAULT,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 235 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'BACKUP LOG,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 236 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE RULE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 26 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'REFERENCES,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 178 AND [protecttype] = 205)
SET @msgStatement = @msgStatement + 'CREATE FUNCTION,'

IF LEN(@msgStatement) > 0
BEGIN
IF RIGHT(@msgStatement, 1) = ','
SET @msgStatement = LEFT(@msgStatement, LEN(@msgStatement) - 1)
SET @msgStatement = 'GRANT' + CHAR(13) +
CHAR(9) + @msgStatement + CHAR(13)
IF @ObjectID<>0
SET @msgStatement=@msgStatement+CHAR(9) + 'ON ' + @ObjectName + CHAR(13)
SET @msgStatement=@msgStatement+CHAR(9) + 'TO ' + @DatabaseRoleName
PRINT @msgStatement
END
SET @msgStatement = ''
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 193 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'SELECT,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 195 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'INSERT,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 197 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'UPDATE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 196 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'DELETE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 224 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'EXECUTE,'
IF EXISTS(SELECT * FROM [dbo].[sysprotects] WHERE [id] = @ObjectID AND [uid] = @DatabaseRoleID AND [action] = 26 AND [protecttype] = 206)
SET @msgStatement = @msgStatement + 'REFERENCES,'
IF LEN(@msgStatement) > 0
BEGIN
IF RIGHT(@msgStatement, 1) = ','
SET @msgStatement = LEFT(@msgStatement, LEN(@msgStatement) - 1)
SET @msgStatement = 'DENY' + CHAR(13) +
CHAR(9) + @msgStatement + CHAR(13) +
CHAR(9) + 'ON ' + @ObjectName + CHAR(13) +
CHAR(9) + 'TO ' + @DatabaseRoleName
PRINT @msgStatement
END
FETCH
NEXT
FROM _sysobjects
INTO
@ObjectID,
@ObjectName
END
CLOSE _sysobjects
DEALLOCATE _sysobjects
DROP TABLE #
PRINT 'GO'
END


强制还原已存在的数据库

USE master
GO
IF EXISTS (SELECT * FROM sysobjects
       WHERE id = object_id(N'[dbo].[spForceRestoreDB]')
      AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
DROP PROCEDURE [dbo].[spForceRestoreDB]
GO
SET QUOTED_IDENTIFIER  OFF    SET ANSI_NULLS  ON
GO

/*
   强制还原已存在的数据库,基本原理是Kill掉数据库的所有会话
   原贴在http://www.sqlservercentral.com/scripts/contributions/827.asp
   在此基础上添加了with move选项

   调用;
   use master
   go
   exec master..spForceRestoreDB 'test'
                                 ,'c:\test.bak'
                                 ,'c:\db\test_data.mdf'
                                 ,'c:\db\test_log.mdf'

   vivianfdlpw 2005.9 引用请保留此信息
*/
CREATE PROCEDURE spForceRestoreDB
    @DatabaseName varchar(50),       --要恢复的数据库名
    @BackupFile varchar(255),        --备份文件路径
    @NewDataFilePath  varchar(255),  --新物理文件位置
    @NewLogFilePath  varchar(255)    --新日志文件位置
WITH ENCRYPTION
AS
BEGIN
SET NOCOUNT ON
 DECLARE @exists int

 IF NOT EXISTS( select name from master.dbo.sysdatabases WHERE name = @DatabaseName)
 BEGIN
 PRINT '  Database ' + @DatabaseName + ' not found '
 PRINT '  Enter valid Datbase name'
 RETURN
 END

 EXEC master.dbo.xp_fileexist @BackupFile , @exists OUTPUT
 if (@exists = 0)
 BEGIN
 PRINT '  File ' + @BackupFile + ' Does bot Exist'
 PRINT '  Database cannot be restored'
 PRINT '  Enter the valid Backup File'
 RETURN
 END

     -- Cursor for all the spids running against this database
 DECLARE SysProc CURSOR LOCAL FORWARD_ONLY DYNAMIC READ_ONLY FOR
 SELECT spid
 FROM master.dbo.sysprocesses
 WHERE dbid = ( SELECT dbid FROM master.dbo.sysdatabases
     WHERE name = @DatabaseName)
   
 DECLARE @SysProcId smallint
 
 -- Opens the Cursor
 OPEN SysProc
 
 -- Fetch the Process ID into the cursor
  FETCH NEXT FROM SysProc INTO @SysProcId
 
 DECLARE @KillStatement char(30)
 
 WHILE @@FETCH_STATUS = 0
 BEGIN
  SET @KillStatement = 'KILL ' + CAST(@SysProcId AS char(30))
 
  -- Kills the processes running against the database
  EXEC (@KillStatement)
 
  FETCH NEXT FROM SysProc INTO @SysProcId
 END
 
 WAITFOR DELAY '000:00:01'

        create table #
       (LogicalName varchar(255),
        PhysicalName varchar(255),
        Type varchar(20),
        FileGroupName varchar(255),
        Size varchar(20),
        MaxSize varchar(20) )
        declare @cmd varchar(200)
                ,@DataLogicName varchar(20)
                ,@logLogicName varchar(20)
        select @cmd = 'RESTORE FILELISTONLY FROM disk = '''+ @BackupFile + ''''
        insert # exec(@cmd)

        select @DataLogicName=LogicalName from # where Type='D'
        select @logLogicName=LogicalName from # where Type='L'
        drop table #

 DECLARE @strSql varchar(2000)

 SET @strSql = 'RESTORE DATABASE '
 SET @strSql = @strSql + QUOTENAME(@DatabaseName) 
 SET @strSql = @strSql + 'FROM  DISK = N'+ '''' + @BackupFile + ''''
 SET @strSql = @strSql + ' WITH  FILE = 1,  NOUNLOAD ,  STATS = 10,  RECOVERY ,  REPLACE'
        SET @strSql = @strSql + ',Move '''+@DataLogicName+''' to '''+@NewDataFilePath+''''
        SET @strSql = @strSql + ',Move '''+@logLogicName+''' to '''+@NewLogFilePath+''''

 --PRINT @strSql
 -- Restore the Database
 EXEC (@strSql)

SET NOCOUNT OFF
END
GO


原贴出处CSDN,具体帖子记不清了,在原来的基础上修改了一点:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_createjob]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_createjob]
GO

create proc p_createjob
@jobname varchar(100),             --作业名称
@sql varchar(8000),                --要执行的命令
@serverName sysname='',            --job server名
@dbname sysname='',                --默认为当前的数据库名
@freqtype varchar(6)='day',        --时间周期,month 月,week 周,day 日
@fsinterval int=1,                 --相对于每日的重复次数
@time int=170000                   --开始执行时间,对于重复执行的作业,将从0点到23:59分
as
if isnull(@dbname,'')='' set @dbname=db_name()

--创建作业
exec msdb..sp_add_job @job_name=@jobname

--创建作业步骤
exec msdb..sp_add_jobstep @job_name=@jobname,
        @step_name = '数据处理',
        @subsystem = 'TSQL',
        @database_name=@dbname,
        @command = @sql,
        @retry_attempts = 5, --重试次数
        @retry_interval = 5  --重试间隔

--创建调度
declare @ftype int,@fstype int,@ffactor int
select @ftype=case @freqtype when 'day' then 4
                                        when 'week' then 8
                                        when 'month' then 16 end
        ,@fstype=case @fsinterval when 1 then 0 else 8 end
if @fsinterval<>1 set @time=0
set @ffactor=case @freqtype when 'day' then 0 else 1 end

EXEC msdb..sp_add_jobschedule @job_name=@jobname,
        @name = '时间安排',
        @freq_type=@ftype ,                        --每天,8 每周,16 每月
        @freq_interval=1,                          --重复执行次数
        @freq_subday_type=@fstype,                 --是否重复执行
        @freq_subday_interval=@fsinterval,         --重复周期
        @freq_recurrence_factor=@ffactor,
        @active_start_time=@time                   --下午17:00:00分执行

if @servername=''
set @servername=@@servername
EXEC msdb..sp_add_jobserver @job_name = @jobname,
     @server_name = @servername

go

--调用
--每月执行的作业
exec p_createjob @jobname='mm'
                 ,@sql='insert A select ''AAA'''
                 ,@servername='FUDAN-OXI9Y1PYT'
                 ,@dbname='test'
                 ,@freqtype='month'
                 ,@time='000000'

*
    重新启动SQLServer服务,要求操作者具有相应权限
    --vivianfdlpw  2005.9 引用请保留此信息
*/

--创建重启脚本
declare @o int,@f int,@t int,@ret int
exec sp_oacreate 'scripting.filesystemobject',@o out
exec sp_oamethod @o,'createtextfile',@f out,'c:\restart.bat',1
exec @ret=sp_oamethod @f,'writeline',NULL,'net stop mssqlserver'
exec @ret=sp_oamethod @f,'writeline',NULL,'net start mssqlserver'

--执行重启脚本
exec master..xp_cmdshell 'c:\restart.bat'


/*
   如果重新启动计算机,请确认mssqlserver账户在管理员账户下运行(非本地系统账户)

*/

exec master..xp_cmdshell 'shutdown /r /f'
Oracle:
select o.obj# as objectId, o.name AS tableName, oc.name AS constraintName,
       decode(c.type#, 1, 'C', 2, 'P', 3, 'U',
              4, 'R', 5, 'V', 6, 'O', 7,'C', '?') as constraintType,
       col.name AS columnName
     
from sys.con$ oc, sys.con$ rc,
     sys.obj$ ro,sys.obj$ o, sys.obj$ oi,
     sys.cdef$ c,
     sys.col$ col, sys.ccol$ cc, sys.attrcol$ ac
where oc.con# = c.con#
  and c.obj# = o.obj#
  and c.rcon# = rc.con#(+)
  and c.enabled = oi.obj#(+)
  and c.robj# = ro.obj#(+)
  and c.type# != 8
  and c.type# != 12       /* don't include log groups */
  and c.con# = cc.con#
  and cc.obj# = col.obj#
  and cc.intcol# = col.intcol#
  and cc.obj# = o.obj#
  and col.obj# = ac.obj#(+)
  and col.intcol# = ac.intcol#(+)
  and o.name = 'your table'
 
SQL Server:

SELECT sysobjects.id objectId,
OBJECT_NAME(sysobjects.parent_obj) tableName,
sysobjects.name constraintName,
sysobjects.xtype AS constraintType,
syscolumns.name AS columnName
FROM sysobjects INNER JOIN sysconstraints
ON sysobjects.xtype in('C', 'F', 'PK', 'UQ', 'D')
 AND sysobjects.id = sysconstraints.constid
LEFT OUTER JOIN syscolumns ON sysconstraints.id = syscolumns.id
WHERE OBJECT_NAME(sysobjects.parent_obj)='your table'
 其实只要使用系统内置的存储过程sp_spaceused就可以得到表的相关信息
如:sp_spaceused 'tablename'


以下是为了方便写的一个存储过程,目的是把当前的所有表的相关信息全部都保存在一个指定的表里面

CREATE PROCEDURE get_tableinfo AS
 
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tablespaceinfo]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
create table  tablespaceinfo                         --创建结果存储表
              (nameinfo varchar(50) , 
               rowsinfo int , reserved varchar(20) , 
               datainfo varchar(20)  , 
               index_size varchar(20) , 
               unused varchar(20) )
 
 
delete from tablespaceinfo --清空数据表
 
declare @tablename varchar(255)  --表名称
 
declare @cmdsql varchar(500)
 
DECLARE Info_cursor CURSOR FOR 
select o.name  
from dbo.sysobjects o where OBJECTPROPERTY(o.id, N'IsTable') = 1 
     and o.name not like N'#%%'  order by o.name
 
OPEN Info_cursor
 
FETCH NEXT FROM Info_cursor 
INTO @tablename 
 
WHILE @@FETCH_STATUS = 0
BEGIN
 
  if exists (select * from dbo.sysobjects where id = object_id(@tablename) and OBJECTPROPERTY(id, N'IsUserTable') = 1)
  execute sp_executesql 
         N'insert into tablespaceinfo  exec sp_spaceused @tbname',
          N'@tbname varchar(255)',
          @tbname = @tablename
 
  FETCH NEXT FROM Info_cursor 
  INTO @tablename 
END
 
CLOSE Info_cursor
DEALLOCATE Info_cursor
GO select *
from tablespaceinfo 
order by cast(left(ltrim(rtrim(reserved)) , len(ltrim(rtrim(reserved)))-2) as int) desc

 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=492223

1. SET DEADLOCK_PRIORITY

说明:控制在发生死锁情况时会话的反应方式。如果两个进程都锁定数据,并且直到其它进程释放自己的锁时,每个进程才能释放自己的锁,即发生死锁情况。

语法:SET DEADLOCK_PRIORITY { LOW | NORMAL | @deadlock_var }

参数:LOW  指定当前会话为首选死锁牺牲品。Microsoft® SQL Server™ 自动回滚死锁牺牲品的事务,并给客户端应用程序返回 1205 号死锁错误信息。
   NORMAL  指定会话返回到默认的死锁处理方法。
   @deadlock_var 是指定死锁处理方法的字符变量。如果指定 LOW,则 @deadlock_var 为 3;如果指定 NORMAL,则 @deadlock_var 为 6。

注释:SET DEADLOCK_PRIORITY 的设置是在执行或运行时设置,而不是在分析时设置。

权限:SET DEADLOCK_PRIORITY 权限默认授予所有用户。

 

2. SET LOCK_TIMEOUT

说明:指定语句等待锁释放的毫秒数。

语法:SET LOCK_TIMEOUT timeout_period

参数:timeout_period 是在 Microsoft® SQL Server™ 返回锁定错误前经过的毫秒数。值为 -1(默认值)时表示没有超时期限(即无限期等待)。
      当锁等待超过超时值时,将返回错误。值为 0 时表示根本不等待,并且一遇到锁就返回信息。

注释:在连接开始时,该设置的值为 -1。设置更改后,新设置在其余的连接时间里一直有效。
   SET LOCK_TIMEOUT 的设置是在执行或运行时设置,而不是在分析时设置。
   READPAST 锁定提示为该 SET 选项提供了另一种方式。

权限:SET LOCK_TIMEOUT 权限默认授予所有用户。

示例:下例将锁超时期限设置为 1,800 毫秒。

   SET LOCK_TIMEOUT 1800
   GO

 

3. @@LOCK_TIMEOUT

说明:返回当前会话的当前锁超时设置,单位为毫秒。

语法:@@LOCK_TIMEOUT

返回类型:integer

注释:SET LOCK_TIMEOUT 允许应用程序设置语句等待阻塞资源的最长时间。当一条语句已等待超过 LOCK_TIMEOUT 所设置的时间,则被锁住的语句将自动取消,并给应用程序返回一条错误信息。
   在一个连接的开始,@@LOCK_TIMEOUT 返回一个 –1值。

示例:下面的示例显示当一个 LOCK_TIMEOUT 值未被设置时的结果集。

   SELECT @@LOCK_TIMEOUT
   下面是结果集:
   ----------------
   -1

   下面的示例设置 LOCK_TIMEOUT 为 1800 毫秒,然后调用 @@LOCK_TIMEOUT。

   SET LOCK_TIMEOUT 1800
   SELECT @@LOCK_TIMEOUT

   下面是结果集:
   ------------------------------
   1800

 

4. SET IDENTITY_INSERT

说明:允许将显式值插入表的标识列中。

语法:SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }

参数:database 是指定的表所驻留的数据库名称。
   owner 是表所有者的名称。
   table 是含有标识列的表名。

注释:任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
   如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
   SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。

权限:执行权限默认授予 sysadmin 固定服务器角色和 db_owner 及 db_ddladmin 固定数据库角色以及对象所有者。

示例:下例创建一个含有标识列的表,并显示如何使用 SET IDENTITY_INSERT 设置填充由 DELETE 语句导致的标识值中的空隙。

   -- Create products table.
   CREATE TABLE products (id int IDENTITY PRIMARY KEY, product varchar(40))
   GO
   -- Inserting values into products table.
   INSERT INTO products (product) VALUES ('screwdriver')
   INSERT INTO products (product) VALUES ('hammer')
   INSERT INTO products (product) VALUES ('saw')
   INSERT INTO products (product) VALUES ('shovel')
   GO

   -- Create a gap in the identity values.
   DELETE products
   WHERE product = 'saw'
   GO

   SELECT *
   FROM products
   GO

   -- Attempt to insert an explicit ID value of 3;
   -- should return a warning.
   INSERT INTO products (id, product) VALUES(3, 'garden shovel')
   GO

   -- SET IDENTITY_INSERT to ON.
   SET IDENTITY_INSERT products ON
   GO

   -- Attempt to insert an explicit ID value of 3
   INSERT INTO products (id, product) VALUES(3, 'garden shovel')
   GO

   SELECT *
   FROM products
   GO

   -- Drop products table.
   DROP TABLE products
   GO

 

5. SET IMPLICIT_TRANSACTIONS

说明:为连接设置隐性事务模式。

语法:SET IMPLICIT_TRANSACTIONS { ON | OFF }

注释:当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式。
   当连接是隐性事务模式且当前不在事务中时,执行下列语句将启动事务:

   ALTER TABLE FETCH REVOKE
   CREATE  GRANT SELECT
   DELETE INSERT TRUNCATE TABLE
   DROP OPEN UPDATE

   如果连接已经在打开的事务中,则上述语句不启动新事务。
   对于因为该设置为 ON 而自动打开的事务,用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。在事务提交后,执行上述任一语句即可启动新事务。
   隐性事务模式将保持有效,直到连接执行 SET IMPLICIT_TRANSACTIONS OFF 语句使连接返回到自动提交模式。在自动提交模式下,如果各个语句成功完成则提交。
   在进行连接时,SQL Server ODBC 驱动程序和用于 SQL Server 的 Microsoft OLE DB 提供程序自动将 IMPLICIT_TRANSACTIONS 设置为 OFF。对来自 DB-Library 应用程序的连接,SET IMPLICIT_TRANSACTIONS 默认为 OFF。
   当 SET ANSI_DEFAULTS 为 ON 时,将启用 SET IMPLICIT_TRANSACTIONS。
   SET IMPLICIT_TRANSACTIONS 的设置是在执行或运行时设置,而不是在分析时设置。

示例:下例演示在将 IMPLICIT_TRANSACTIONS 设置为 ON 时显式或隐式启动事务。它使用 @@TRANCOUNT 函数演示打开的事务和关闭的事务。

   USE pubs
   GO

   CREATE table t1 (a int)
   GO
   INSERT INTO t1 VALUES (1)
   GO

   PRINT 'Use explicit transaction'
   BEGIN TRAN
   INSERT INTO t1 VALUES (2)
   SELECT 'Tran count in transaction'= @@TRANCOUNT
   COMMIT TRAN
   SELECT 'Tran count outside transaction'= @@TRANCOUNT
   GO

   PRINT 'Setting IMPLICIT_TRANSACTIONS ON'
   GO
   SET IMPLICIT_TRANSACTIONS ON
   GO

   PRINT 'Use implicit transactions'
   GO
   -- No BEGIN TRAN needed here.
   INSERT INTO t1 VALUES (4)
   SELECT 'Tran count in transaction'= @@TRANCOUNT
   COMMIT TRAN
   SELECT 'Tran count outside transaction'= @@TRANCOUNT
   GO

   PRINT 'Use explicit transactions with IMPLICIT_TRANSACTIONS ON'
   GO
   BEGIN TRAN
   INSERT INTO t1 VALUES (5)
   SELECT 'Tran count in transaction'= @@TRANCOUNT
   COMMIT TRAN
   SELECT 'Tran count outside transaction'= @@TRANCOUNT
   GO

   SELECT * FROM t1
   GO

   -- Need to commit this tran too!
   DROP TABLE t1
   COMMIT TRAN
   GO

 

6. SET NOCOUNT
说明:使返回的结果中不包含有关受 Transact-SQL 语句影响的行数的信息。

语法:SET NOCOUNT { ON | OFF }

注释:当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。
   即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。
   当 SET NOCOUNT 为 ON 时,将不给客户端发送存储过程中的每个语句的 DONE_IN_PROC 信息。当使用 Microsoft® SQL Server™ 提供的实用工具执行查询时,在 Transact-SQL 语句(如 SELECT、INSERT、UPDATE 和 DELETE)结束时将不会在查询结果中显示"nn rows affected"。
   如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。
   SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。

权限:SET NOCOUNT 权限默认授予所有用户。

示例:下例在 osql 实用工具或 SQL Server 查询分析器中执行时,可防止显示有关受影响的行数的信息。

   USE pubs
   GO
   -- Display the count message.
   SELECT au_lname
   FROM authors
   GO
   USE pubs
   GO
   -- SET NOCOUNT to ON and no longer display the count message.
   SET NOCOUNT ON
   GO
   SELECT au_lname
   FROM authors
   GO
   -- Reset SET NOCOUNT to OFF.
   SET NOCOUNT OFF
   GO

 

7. @@ROWCOUNT
说明:返回受上一语句影响的行数。

语法:@@ROWCOUNT

返回类型:integer

注释:任何不返回行的语句将这一变量设置为 0 ,如 IF 语句。

示例:下面的示例执行 UPDATE 语句并用 @@ROWCOUNT 来检测是否有发生更改的行。

   UPDATE authors SET au_lname = 'Jones'
   WHERE au_id = '999-888-7777'
   IF @@ROWCOUNT = 0
      print 'Warning: No rows were updated'

 

8. SET ROWCOUNT

说明:使 Microsoft® SQL Server™ 在返回指定的行数之后停止处理查询。

语法:SET ROWCOUNT { number | @number_var }

参数:number | @number_var 是在停止给定查询之前要处理的行数(整数)。

注释:建议将当前使用 SET ROWCOUNT 的 DELETE、INSERT 和 UPDATE 语句重新编写为使用 TOP 语法。有关更多信息,请参见 DELETE、INSERT 或 UPDATE。
   对于在远程表和本地及远程分区视图上执行的 INSERT、UPDATE 和 DELETE 语句,忽略 SET ROWCOUNT 选项设置。
   若要关闭该选项(以便返回所有的行),请将 SET ROWCOUNT 指定为 0。
   说明  设置 SET ROWCOUNT 选项将使大多数 Transact-SQL 语句在已受指定数目的行影响后停止处理。这包括触发器和 INSERT、UPDATE 及 DELETE 等数据修改语句。ROWCOUNT 选项对动态游标无效,但限制键集的行集和不感知游标。使用该选项时应谨慎,它主要与 SELECT 语句一起使用。
   如果行数的值较小,则 SET ROWCOUNT 替代 SELECT 语句 TOP 关键字。
   SET ROWCOUNT 的设置是在执行或运行时设置,而不是在分析时设置。

权限:SET ROWCOUNT 权限默认授予所有用户。

示例:SET ROWCOUNT 在指定的行数后停止处理。在下例中,注意有 x 行满足预付款少于或等于 $5,000 的条件;但是,从更新所返回的行数中可以看出并非所有的行都得到处理。ROWCOUNT 影响所有的 Transact-SQL 语句。

   USE pubs
   GO
   SELECT count(*) AS Cnt
   FROM titles
   WHERE advance >= 5000
   GO

   下面是结果集:

   Cnt      
   -----------
   11         

   (1 row(s) affected)

   现在,将 ROWCOUNT 设置为 4,并更新预付款等于或大于 $5,000 的所有行。

   -- SET ROWCOUNT to 4.
   SET ROWCOUNT 4
   GO
   UPDATE titles
   SET advance = 5000
   WHERE advance >= 5000
   GO

 

9. SET TRANSACTION ISOLATION LEVEL
说明:控制由连接发出的所有 Microsoft® SQL Server™ SELECT 语句的默认事务锁定行为。

语法:SET TRANSACTION ISOLATION LEVEL
   { READ COMMITTED
       | READ UNCOMMITTED
       | REPEATABLE READ
       | SERIALIZABLE
   }

参数:READ COMMITTED 指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。
   READ UNCOMMITTED 执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。
   REPEATABLE READ 锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。
   SERIALIZABLE 在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

注释:一次只能设置这些选项中的一个,而且设置的选项将一直对那个连接保持有效,直到显式更改该选项为止。这是默认行为,除非在语句的 FROM 子句中在表级上指定优化选项。
   SET TRANSACTION ISOLATION LEVEL 的设置是在执行或运行时设置,而不是在分析时设置。

示例:下例为会话设置 TRANSACTION ISOLATION LEVEL。对于每个后续 Transact-SQL 语句,SQL Server 将所有共享锁一直控制到事务结束为止。

   SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
   GO
   BEGIN TRANSACTION
   SELECT * FROM publishers
   SELECT * FROM authors
   ...
   COMMIT TRANSACTION

 

10. SET XACT_ABORT

说明:指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。

语法:SET XACT_ABORT { ON | OFF }

注释:当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
   对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。有关更多信息,请参见分布式查询和分布式事务。
   SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。

示例:下例导致在含有其它 Transact-SQL 语句的事务中发生违反外键错误。在第一个语句集中产生错误,但其它语句均成功执行且事务成功提交。在第二个语句集中,SET XACT_ABORT 设置为 ON。这导致语句错误使批处理终止,并使事务回滚。

   CREATE TABLE t1 (a int PRIMARY KEY)
   CREATE TABLE t2 (a int REFERENCES t1(a))
   GO
   INSERT INTO t1 VALUES (1)
   INSERT INTO t1 VALUES (3)
   INSERT INTO t1 VALUES (4)
   INSERT INTO t1 VALUES (6)
   GO
   SET XACT_ABORT OFF
   GO
   BEGIN TRAN
   INSERT INTO t2 VALUES (1)
   INSERT INTO t2 VALUES (2) /* Foreign key error */
   INSERT INTO t2 VALUES (3)
   COMMIT TRAN
   GO

   SET XACT_ABORT ON
   GO

   BEGIN TRAN
   INSERT INTO t2 VALUES (4)
   INSERT INTO t2 VALUES (5) /* Foreign key error */
   INSERT INTO t2 VALUES (6)
   COMMIT TRAN
   GO

   /* Select shows only keys 1 and 3 added.
      Key 2 insert failed and was rolled back, but
      XACT_ABORT was OFF and rest of transaction
      succeeded.
      Key 5 insert error with XACT_ABORT ON caused
      all of the second transaction to roll back. */

   SELECT *
   FROM t2
   GO

   DROP TABLE t2
   DROP TABLE t1
   GO

/*
  函数名称: GetRecordFromPage
  函数功能: 获取指定页的数据
  参数说明: @tblName      包含数据的表名
           @fldName      关键字段名
           @fldIndex     无重复索引字段
           @PageSize     每页记录数
           @PageIndex    要获取的页码
           @OrderType    排序类型, 0 - 升序, 1 - 降序
           @strWhere     查询条件 (注意: 不要加 where)
  作  者: 铁拳
  邮  箱: sunjianhua_kki@sina.com
  创建时间: 2004-07-04
  修改时间: 2005-09-21
*/
CREATE PROCEDURE GetRecordFromPage
    @tblName      varchar(255),       -- 表名
    @fldName      varchar(255),       -- 字段名
    @fldIndex     varchar(255)='',    -- 无重复索引字段
    @PageSize     int = 10,           -- 页尺寸
    @PageIndex    int = 1,            -- 页码
    @OrderType    bit = 0,            -- 设置排序类型, 非 0 值则降序
    @strWhere     varchar(2000) = ''  -- 查询条件 (注意: 不要加 where)
AS

declare @strSQL   varchar(6000)       -- 主语句
declare @strTmp   varchar(1000)       -- 临时变量
declare @strOrder varchar(500)        -- 排序类型
declare @strField varchar(1000)       -- 用来联合的字段

if @PageIndex < 1
    return

set @strField = '[' + @fldName + ']'

-- 计算后的数据精确到小数点后 33 位
if @fldIndex != ''
    set @strField = ' convert(numeric(38,33), [' + @fldName
        + ']) + convert(numeric(38,33), [' + @fldIndex
        + '] / 10000000000000000000000000000) '

if @OrderType != 0
begin
    set @strTmp = '<(select min'
    set @strOrder = ' order by ' + @strField + ' desc'
end
else
begin
    set @strTmp = '>(select max'
    set @strOrder = ' order by ' + @strField + ' asc'
end

set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
    + @tblName + '] where ' + @strField + @strTmp
    + '(tmpIndex) from (select top ' + str((@PageIndex-1)*@PageSize) + @strField
    + ' tmpIndex from [' + @tblName + ']' + @strOrder + ') as tblTmp)'
    + @strOrder

if @strWhere != ''
    set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
        + @tblName + '] where ' + @strField + @strTmp
        + '(tmpIndex) from (select top ' + str((@PageIndex-1)*@PageSize) + @strField
        + ' tmpIndex from [' + @tblName + '] where ' + @strWhere + ' '
        + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder

if @PageIndex = 1
begin
    set @strTmp = ''
    if @strWhere != ''
        set @strTmp = ' where (' + @strWhere + ')'

    set @strSQL = 'select top ' + str(@PageSize) + ' * from ['
        + @tblName + ']' + @strTmp + ' ' + @strOrder
end

exec (@strSQL)
GO

 

 

 


 

posted on 2006-04-27 13:24  Sanle  阅读(869)  评论(0编辑  收藏  举报

导航