SQLSERVER存储过程语法详解

CREATE PROC [ EDURE ] procedure_name [ ; number ]
    [ { @parameter data_type }
        [ VARYING ] [ = default ] [ OUTPUT ]
    ] [ ,...n ]

[ WITH
    { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]

[ FOR REPLICATION ]

AS sql_statement [ ...n ]

 

@parameter 
过程当中的参数。在 Create PROCEDURE 语句中能够声明一个或多个参数。用户必须在执行过程时提供每一个所声明参数的值(除非定义了该参数的默认值)java

OUTPUT 
代表参数是返回参数。该选项的值能够返回给 EXEC[UTE]。使用 OUTPUT 参数可将信息返回给调用过程。Text、ntext 和 image 参数可用做 OUTPUT 参数。使用 OUTPUT 关键字的输出参数能够是游标占位符。 sql

AS :指定过程要执行的操做数据库

 

SQLSERVER:
变量的声明:
声明变量时必须在变量前加@符号 
DECLARE @I INT

变量的赋值:
变量赋值时变量前必须加set
SET @I = 30

声明多个变量:
DECLARE @s varchar(10),@a INToracle

 

 

 

 

 

 

 

 

----------------------------------------------------------------------------------------数据库设计

oracle的建表sql转成sqlserver的建表sql时的注意点 :
1.全部的comment语句须要删除。
2.clob类型转换为text类型。
3.blob类型转换为image类型。
4.number类型转换为int,number(16,2)等转换为decimal(16,2),number(18)转换为bigint。
5.default sysdate改成default getDate()。
6.to_date('2009-12-18','yyyy-mm-dd')改成cast('2009-12-18'  as   datetime)

SQLSERVER:
变量的声明:
声明变量时必须在变量前加@符号
DECLARE @I INT

变量的赋值:
变量赋值时变量前必须加set
SET @I = 30

声明多个变量:
DECLARE @s varchar(10),@a INT

if语句:ide

Java代码   收藏代码
  1. if ..  
  2. begin  
  3.   ...  
  4. end  
  5. else if ..  
  6. begin  
  7.   ...  
  8. end  
  9. else  
  10. begin  
  11.   ...  
  12. end   

 Example:函数

Sql代码   收藏代码
  1. DECLARE @d INT  
  2. set @d = 1  
  3. IF @d = 1 BEGIN  
  4.    PRINT '正确'  
  5. END  
  6. ELSE BEGIN  
  7.    PRINT '错误'  
  8. END  

 
多条件选择语句:
Example:sqlserver

Sql代码   收藏代码
  1. declare @today int  
  2. declare @week nvarchar(3)  
  3. set @today=3  
  4. set @week= case  
  5.      when @today=1 then '星期一'  
  6.      when @today=2 then '星期二'  
  7.      when @today=3 then '星期三'  
  8.      when @today=4 then '星期四'  
  9.      when @today=5 then '星期五'  
  10.      when @today=6 then '星期六'  
  11.      when @today=7 then '星期日'  
  12.      else '值错误'  
  13. end  
  14. print @week  

 
循环语句:fetch

Java代码   收藏代码
  1. WHILE 条件 BEGIN    
  2. 执行语句  
  3. END    

 Example:加密

Java代码   收藏代码
  1. DECLARE @i INT  
  2. SET @i = 1  
  3. WHILE @i<1000000 BEGIN  
  4. set @i=@i+1  
  5. END  

 

定义游标:

Sql代码   收藏代码
  1. DECLARE @cur1 CURSOR FOR SELECT .........  
  2.   
  3. OPEN @cur1  
  4. FETCH NEXT FROM @cur1 INTO 变量  
  5. WHILE(@@FETCH_STATUS=0)  
  6. BEGIN  
  7. 处理.....  
  8. FETCH NEXT FROM @cur1 INTO 变量  
  9. END  
  10. CLOSE @cur1  
  11. DEALLOCATE @cur1   

 

Sql代码   收藏代码
  1. AS  
  2.   
  3. declare @CATEGORY_CI_TABLENAME VARCHAR(50) =''  
  4. declare @result VARCHAR(2000) = ''  
  5. declare @CI_ID DECIMAL = 0  
  6. declare @num int = 1  
  7. declare @countnum int = 1  
  8.   
  9. BEGIN  
  10. select  @countnum = count(ATTRIBUTE_CONFIG_ID) from T_ATTRIBUTE_CONFIG where CMDB_UPDATE_FLAG= 'Y' and CATEGORY_CODE =@CATEGORY_CODE  
  11.    
  12. IF (@ATTRIBUTE2='A')  
  13.   begin    
  14.         DECLARE MyCursor CURSOR for select ATTRIBUTE_CONFIG_CODE from T_ATTRIBUTE_CONFIG where  CMDB_UPDATE_FLAG= 'Y' and CATEGORY_CODE =@CATEGORY_CODE  
  15.          OPEN MyCursor FETCH NEXT FROM MyCursor INTO @CONFIG_CODE  
  16.                 set @result = @result+@CONFIG_CODE+','  
  17.              WHILE @@FETCH_STATUS = 0  
  18.                     BEGIN  
  19.                     FETCH NEXT FROM MyCursor INTO @CONFIG_CODE  
  20.                     set @num = @num+ 1  
  21.                         if(@num<@countnum)   
  22.                             begin  
  23.                                 set @result = @result+@CONFIG_CODE+','  
  24.                             end   
  25.                         else if(@num=@countnum)   
  26.                              begin  
  27.                                 set @result = @result +@CONFIG_CODE  
  28.                              end   
  29.                     END  
  30.             CLOSE MyCursor   
  31.             DEALLOCATE MyCursor   
  32.         set @result = 'insert into ' + @ATTRIBUTE1 + '(' + @result +') select '+ @result +' from '+@CATEGORY_CI_TABLENAME +' where CI_ORDER_LINE_ID='+@KEY_ID  
  33.   end             
  34.  else if((@ATTRIBUTE2='U'))  

 

临时表:

-- Select INTO 从一个查询的计算结果中建立一个新表。 数据并不返回给客户端,这一点和普通的Select 不一样。 新表的字段具备和 Select 的输出字段相关联(相同)的名字和数据类型。
        select * into NewTable
            from Uname

-- Insert INTO ABC Select
        -- 表ABC必须存在 
        -- 把表Uname里面的字段Username复制到表ABC
        Insert INTO ABC Select Username FROM Uname

-- 建立临时表
        Create TABLE #temp(
            UID int identity(1, 1) PRIMARY KEY,
            UserName varchar(16),
            Pwd varchar(50),
            Age smallint,
            Sex varchar(6)
        )
        
-- 打开临时表
        Select * from #temp

 

 一、局部临时表(#开头)只对当前链接有效,当前链接断开时自动删除。
二、全局临时表(##开头)对其它链接也有效,在当前链接和其余访问过它的链接都断开时自动删除。
三、无论局部临时表仍是全局临时表,只要链接有访问权限,均可以用drop table #Tmp(或者drop table ##Tmp)来显式删除临时表。

临时表对执行效率应该影响不大,只要不是太过份,相反能够提升效率特别是链接查询的地方,只要你的数据库临时表空间足够
游标多,会严重执行效率,能免则免!

 

临时表在不一样数据库设计中的做用

SQLSERVER 存储过程 语法

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

其余:

--有输入参数的存储过程--

create proc GetComment

(@commentid int)

as

select * from Comment where CommentID=@commentid

 

--有输入与输出参数的存储过程--

create proc GetCommentCount

@newsid int,

@count int output

as

select @count=count(*) from Comment where NewsID=@newsid

 

 

--返回单个值的函数--

create function MyFunction

(@newsid int)

returns int

as

begin

declare @count int

select @count=count(*) from Comment where NewsID=@newsid

return @count

end

 

--调用方法--

declare @count int

exec @count=MyFunction 2

print @count

 

--返回值为表的函数--

Create function GetFunctionTable

(@newsid int)

returns table

as

return

(select * from Comment where NewsID=@newsid)

 

--返回值为表的函数的调用--

select * from GetFunctionTable(2)

 

 

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

SQLServer 存储过程当中不拼接SQL字符串实现多条件查询

 之前拼接的写法
  set @sql=' select * from table where 1=1 '
  if (@addDate is not null) 
   set @sql = @sql+' and addDate = '+ @addDate + ' ' 
  if (@name <>'' and is not null) 
   set @sql = @sql+ ' and name = ' + @name + ' '
  exec(@sql)
下面是 不采用拼接SQL字符串实现多条件查询的解决方案
  第一种写法是 感受代码有些冗余
  if (@addDate is not null) and (@name <> '') 
   select * from table where addDate = @addDate and name = @name 
  else if (@addDate is not null) and (@name ='') 
   select * from table where addDate = @addDate 
  else if(@addDate is null) and (@name <> '') 
   select * from table where and name = @name 
  else if(@addDate is null) and (@name = '') 
  select * from table 
  第二种写法是 
  select * from table where (addDate = @addDate or @addDate is null) and (name = @name or @name = '') 
  第三种写法是 
  SELECT * FROM table where 
  addDate = CASE @addDate IS NULL THEN addDate ELSE @addDate END, 
  name = CASE @name WHEN '' THEN name ELSE @name END

 

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

 

SQLSERVER存储过程基本语法

 

1、定义变量

--简单赋值
declare @a  int
set @a=5
print @a
   
--使用select语句赋值
declare @user1 nvarchar(50)
select @user1= '张三'
print @user1
declare @user2 nvarchar(50)
select @user2 =  Name from ST_User  where ID=1
print @user2
   
--使用update语句赋值
declare @user3 nvarchar(50)
update ST_User  set @user3 =  Name where ID=1
print @user3

 

2、表、临时表、表变量

--建立临时表1
create table #DU_User1
(
      [ID] [ int  NOT NULL ,
      [Oid] [ int ]  NOT NULL ,
      [Login] [nvarchar](50)  NOT NULL ,
      [Rtx] [nvarchar](4)  NOT NULL ,
      [ Name ] [nvarchar](5)  NOT NULL ,
      [ Password ] [nvarchar]( max )  NULL ,
      [State] [nvarchar](8)  NOT NULL
);
--向临时表1插入一条记录
insert into #DU_User1 (ID,Oid,[Login],Rtx, Name ,[ Password ],State)  values (100,2, 'LS' ,'0000' , '临时' , '321' , '特殊' );
   
--从ST_User查询数据,填充至新生成的临时表
select *  into #DU_User2  from ST_User  where ID<8
   
--查询并联合两临时表
select *  from #DU_User2  where ID<3  union select *  from #DU_User1
   
--删除两临时表
drop table #DU_User1
drop table #DU_User2
 
--建立临时表
CREATE TABLE #t
(
     [ID] [ int ]  NOT NULL ,
     [Oid] [ int ]  NOT NULL ,
     [Login] [nvarchar](50)  NOT NULL ,
     [Rtx] [nvarchar](4)  NOT NULL ,
     [ Name ] [nvarchar](5)  NOT NULL ,
     [ Password ] [nvarchar]( max )  NULL ,
     [State] [nvarchar](8)  NOT NULL ,
)
   
--将查询结果集(多条数据)插入临时表
insert into #t  select *  from ST_User
--不能这样插入
--select * into #t from dbo.ST_User
   
--添加一列,为int型自增加子段
alter table #t  add [myid]  int NOT NULL IDENTITY(1,1)
--添加一列,默认填充全球惟一标识
alter table #t  add [myid1] uniqueidentifier  NOT NULL default (newid())
   
select *  from #t
drop table #t
--给查询结果集增长自增加列
   
--无主键时:
select IDENTITY( int ,1,1) as ID,  Name ,[Login],[ Password ]  into #t  from ST_User
select *  from #t
   
--有主键时:
select ( select SUM (1)  from ST_User  where ID<= a.ID)  as myID,*  from ST_User a  order bymyID
--定义表变量
declare @t  table
(
     id  int not null ,
     msg nvarchar(50)  null
)
insert into @t  values (1, '1' )
insert into @t  values (2, '2' )
select *  from @t

 3、循环

--while循环计算1到100的和
declare @a  int
declare @ sum int
set @a=1
set @ sum =0
while @a<=100
begin
     set @ sum +=@a
     set @a+=1
end
print @ sum

4、条件语句

--if,else条件分支
if(1+1=2)
begin
     print  '对'
end
else
begin
     print  '错'
end
   
--when then条件分支
declare @today  int
declare @week nvarchar(3)
set @today=3
set @week= case
     when @today=1  then '星期一'
     when @today=2  then '星期二'
     when @today=3  then '星期三'
     when @today=4  then '星期四'
     when @today=5  then '星期五'
     when @today=6  then '星期六'
     when @today=7  then '星期日'
     else '值错误'
end
print @week

 

5、游标

declare @ID  int
declare @Oid  int
declare @Login  varchar (50)
   
--定义一个游标
declare user_cur  cursor for select ID,Oid,[Login]  from ST_User
--打开游标
open user_cur
while @@fetch_status=0
begin
--读取游标
     fetch next from user_cur  into @ID,@Oid,@Login
     print @ID
     --print @Login
end
close user_cur
--摧毁游标
deallocate user_cur

6、触发器

   触发器中的临时表:

  Inserted 
  存放进行insert和update 操做后的数据 
  Deleted 
  存放进行delete 和update操做前的数据

--建立触发器
Create trigger User_OnUpdate 
     On ST_User 
     for Update  
As  
     declare @msg nvarchar(50)
     --@msg记录修改状况
     select @msg = N '姓名从“' + Deleted. Name + N '”修改成“' + Inserted. Name +  '”' fromInserted,Deleted
     --插入日志表
     insert into [LOG](MSG) values (@msg)
       
--删除触发器
drop trigger User_OnUpdate

7、存储过程

--建立带output参数的存储过程
CREATE PROCEDURE PR_Sum
     @a  int ,
     @b  int ,
     @ sum int output
AS
BEGIN
     set @ sum =@a+@b
END
   
--建立Return返回值存储过程
CREATE PROCEDURE PR_Sum2
     @a  int ,
     @b  int
AS
BEGIN
     Return @a+@b
END
       
--执行存储过程获取output型返回值
declare @mysum  int
execute PR_Sum 1,2,@mysum  output
print @mysum
   
--执行存储过程获取Return型返回值
declare @mysum2  int
execute @mysum2= PR_Sum2 1,2
print @mysum2
 

   

8、自定义函数

  函数的分类:

    1)标量值函数

    2)表值函数

        a:内联表值函数

        b:多语句表值函数

    3)系统函数

 

--新建标量值函数
create function FUNC_Sum1
(
     @a  int ,
     @b  int
)
returns int
as
begin
     return @a+@b
end
   
--新建内联表值函数
create function FUNC_UserTab_1
(
     @myId  int
)
returns table
as
return ( select *  from ST_User  where ID<@myId)
   
--新建多语句表值函数
create function FUNC_UserTab_2
(
     @myId  int
)
returns @t  table
(
     [ID] [ int ]  NOT NULL ,
     [Oid] [ int ]  NOT NULL ,
     [Login] [nvarchar](50)  NOT NULL ,
     [Rtx] [nvarchar](4)  NOT NULL ,
     [ Name ] [nvarchar](5)  NOT NULL ,
     [ Password ] [nvarchar]( max )  NULL ,
     [State] [nvarchar](8)  NOT NULL
)
as
begin
     insert into @t  select *  from ST_User  where ID<@myId
     return
end
   
--调用表值函数
select *  from dbo.FUNC_UserTab_1(15)
--调用标量值函数
declare @s  int
set @s=dbo.FUNC_Sum1(100,50)
print @s
   
--删除标量值函数
drop function FUNC_Sum1

谈谈自定义函数与存储过程的区别:

1、自定义函数:

  1. 能够返回表变量

  2. 限制颇多,包括

    不能使用output参数;

    不能用临时表;

    函数内部的操做不能影响到外部环境;

    不能经过select返回结果集;

    不能update,delete,数据库表;

  3. 必须return 一个标量值或表变量

  自定义函数通常用在复用度高,功能简单单一,争对性强的地方。

2、存储过程

  1. 不能返回表变量

  2. 限制少,能够执行对数据库表的操做,能够返回数据集

  3. 能够return一个标量值,也能够省略return

   存储过程通常用在实现复杂的功能,数据操纵方面。

 

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

SqlServer存储过程--实例

实例1:只返回单一记录集的存储过程。

  表银行存款表(bankMoney)的内容以下

 

Id

userID

Sex

Money

001

Zhangsan

30

002

Wangwu

50

003

Zhangsan

40

 

要求1:查询表bankMoney的内容的存储过程

create procedure sp_query_bankMoney
as
select * from bankMoney
go
exec sp_query_bankMoney

注*  在使用过程当中只须要把T-Sql中的SQL语句替换为存储过程名,就能够了很方便吧!

实例2(向存储过程当中传递参数):

加入一笔记录到表bankMoney,并查询此表中userID= Zhangsan的全部存款的总金额。

Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output
with encryption ---------加密
as
insert into bankMoney (id,userID,sex,Money)
Values(@param1,@param2,@param3, @param4)
select @param5=sum(Money) from bankMoney where userID='Zhangsan'
go
在SQL Server查询分析器中执行该存储过程的方法是:
declare @total_price int
exec insert_bank '004','Zhangsan','男',100,@total_price output
print '总余额为'+convert(varchar,@total_price)
go

在这里再啰嗦一下存储过程的3种传回值(方便正在看这个例子的朋友不用再去查看语法内容):

1.以Return传回整数
2.以output格式传回参数
3.Recordset

传回值的区别:

output和return均可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中。

实例3:使用带有复杂 SELECT 语句的简单过程

  下面的存储过程从四个表的联接中返回全部做者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。

  USE pubs
IF EXISTS (SELECT name FROM sysobjects
         WHERE name = 'au_info_all' AND type = 'P')
   DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
GO

  au_info_all 存储过程能够经过如下方法执行:

  EXECUTE au_info_all
-- Or
EXEC au_info_all

  若是该过程是批处理中的第一条语句,则可以使用:

  au_info_all

实例4:使用带有参数的简单过程

  CREATE PROCEDURE au_info
   @lastname varchar(40),
   @firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
   WHERE  au_fname = @firstname
      AND au_lname = @lastname
GO

  au_info 存储过程能够经过如下方法执行:

  EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'

  若是该过程是批处理中的第一条语句,则可以使用:

  au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'

 

 实例5:使用带有通配符参数的简单过程

CREATE PROCEDURE au_info2
@lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
   ON a.au_id = ta.au_id INNER JOIN titles t
   ON t.title_id = ta.title_id INNER JOIN publishers p
   ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
   AND au_lname LIKE @lastname
GO

  au_info2 存储过程能够用多种组合执行。下面只列出了部分组合:

  EXECUTE au_info2
-- Or
EXECUTE au_info2 'Wh%'
-- Or
EXECUTE au_info2 @firstname = 'A%'
-- Or
EXECUTE au_info2 '[CK]ars[OE]n'
-- Or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- Or
EXECUTE au_info2 'H%', 'S%'

  = 'proc2'

实例6:if...else

存储过程,其中@case做为执行update的选择依据,用if...else实现执行时根据传入的参数执行不一样的修改. 
--下面是if……else的存储过程: 
if exists (select 1 from sysobjects where name = 'Student' and type ='u' )
drop table Student
go

if exists (select 1 from sysobjects where name = 'spUpdateStudent' and type ='p' )
drop proc spUpdateStudent
go

create table Student
(
fName nvarchar (10),
fAge 

smallint ,fDiqu varchar (50),fTel  int )goinsert into Student values ('X.X.Y' , 28, 'Tesing' , 888888)gocreate proc spUpdateStudent(@fCase int ,@fName nvarchar (10),@fAge smallint ,@fDiqu varchar (50),@fTel  int )as update Studentset fAge = @fAge, -- 传 1,2,3 都要更新 fAge 不须要用 case fDiqu = (case when @fCase = 2 or @fCase = 3 then @fDiqu else fDiqu end ),fTel  = (case when @fCase = 3 then @fTel else fTel end )where fName = @fNameselect * from Studentgo-- 只改 Age exec spUpdateStudent@fCase = 1,@fName = N'X.X.Y' ,@fAge = 80,@fDiqu = N'Update' ,@fTel  = 1010101-- 改 Age 和 Diqu exec spUpdateStudent@fCase = 2,@fName = N'X.X.Y' ,@fAge = 80,@fDiqu = N'Update' ,@fTel  = 1010101-- 全改 exec spUpdateStudent@fCase = 3,@fName = N'X.X.Y' ,@fAge = 80,@fDiqu = N'Update' ,@fTel  = 1010101

相关文章
相关标签/搜索