T-SQL的存储过程

1.简介

    存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。而且这个代码块是编译过了放在数据库端的,后台的代码比如php CI框架可以直接调用它:

<?php
    $sql="exec prec_xxx";
    $query = $this->db->query($sql);
?>

    由于数据库是先编译后执行的,所以存储过程是一个编译过的代码块的话,执行效率要比在程序里用T-SQL语句高。

    当然存储过程还有其他优点比如上面的例子只传送了13个字节,相比于打断的T-sql语句要节省带宽。

2.分类

   存储过程包括系统存储过程和用户自定义的存储过程。

  系统存储过程是系统创建的存储过程,目的在于能够方便的从系统表中查询信息或完成与更新数据库表相关的管理任务或其他的系统管理任务。系统存储过程主要存储在master数据库中,以“sp”下划线开头的存储过程。例如下列表单中就包含一些系统存储过程,可以使用exec执行:

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 

    用户自定义存储过程,创建语法:

create proc | procedure pro_name
    [{@参数数据类型} [=默认值] [output],
     {@参数数据类型} [=默认值] [output],
     ....
    ]
as
    SQL_statements

3.举例

  下例为一个T-SQL存储过程(例如是prec_xxxx),用于将一系列表中的一些字段提取出来,返回给php程序。

as
BEGIN
declare @rluid uniqueidentifier 
--创建临时表
IF OBJECT_ID('tempdb..#tab') IS NOT NULL
   DROP TABLE #tab
select convert(varchar(50),rl_uid) rl_uid ,rl_name, convert(varchar(300),'') menunames,
convert(varchar(2000),'') usernames,isnull(ve.emp_name,cve.NAME)emp_name,convert(varchar(10),rl_updatedate,120) rl_updatedate 
into #tab
from t_role tr 
left join v_employee ve on ve.emp_ssn = tr.rl_createuser
left join ttm.dbo.chrm_view_employee cve on cve.EMPLOYEE_ID = tr.rl_createuser 
--创建游标
declare rolelist cursor 
for
select rl_uid 
from t_role order by rl_updatedate desc
open rolelist 
    fetch next from rolelist into @rluid 
        while(@@fetch_status=0)
        begin
                --角色对应的菜单
                declare @menunames varchar(300)
                declare @muname varchar(50)
                set @menunames = ''
                declare menulist cursor 
                for
                select tu.mu_name from t_role_menu tm
                inner join t_menu tu on tm.mu_uid = tu.mu_uid
                where tm.rl_uid = @rluid
                open menulist 
                    declare @i int
                    set @i = 0
                    fetch next from menulist into @muname 
                        while(@@fetch_status=0)
                        begin
                            if @i=0
                            begin
                                set @menunames = @menunames+@muname
                            end
                            else
                            begin
                                set @menunames = @menunames+' , '+@muname
                            end
                        set @i = @i +  1 
                        fetch next from menulist into @muname 
                        end
                close menulist
                deallocate menulist
                update #tab set menunames = @menunames where rl_uid = @rluid
                --角色对应的用户
                declare @usernames varchar(2000)
                declare @username varchar(50)
                set @usernames = ''
                declare userlist cursor 
                for
                select isnull(ve.emp_name,cve.name)emp_name  from t_role_user tu
                left join v_employee ve on tu.emp_ssn = ve.emp_ssn
                left join ttm.dbo.chrm_view_employee cve on cve.EMPLOYEE_ID = tu.emp_ssn
                where rl_uid =  @rluid
                open userlist 
                    declare @j int
                    set @j = 0
                    fetch next from userlist into @username 
                        while(@@fetch_status=0)
                        begin
                            if @j=0
                            begin
                                set @usernames = @usernames+@username
                            end
                            else
                            begin
                                set @usernames = @usernames+' , '+@username
                            end
                        set @j = @j +  1 
                        fetch next from userlist into @username 
                        end
                close userlist
                deallocate userlist
                update #tab set usernames = @usernames where rl_uid = @rluid
        fetch next from rolelist into @rluid
        end
close rolelist
deallocate rolelist    
select rl_uid,rl_name,menunames,convert(text,usernames)usernames,emp_name,rl_updatedate from #tab
END

 

 上面的代码看完一定会对SQL之所以被称为语言表示强烈认可,各种变量呀,循环呀,很像其他编程语言的feel。当然有很多地方可能不够简洁,有人说是它是面向集合的语言。。。有意思。

    

posted on 2015-07-07 20:50  福生  阅读(344)  评论(0编辑  收藏  举报

导航