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

相關文章
相關標籤/搜索