1. 程式人生 > >數據庫的存儲過程

數據庫的存儲過程

with 多個 存儲過程 最大 group 完成 支持 rule create

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/yelin042/article/details/77512960

存儲過程的優缺點
  ◆優點:
  執行速度更快。存儲過程只在創造時進行編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程執行速度更快。
  存儲過程用於處理復雜的操作時,程序的可讀性更強、網絡的負擔更小。
  使用存儲過程封裝事務性能更佳。
  能有效的放註入,安全性更好。
  可維護性高,在一些業務規則發生變化時,有時只需調整存儲過程即可,而不用改動和重編輯程序。
  更好的代碼重用。
  ◆ 缺點:
  存儲過程將給服務器帶來額外的壓力。

   存儲過程多多時維護比較困難。
  移植性差,在升級到不同的數據庫時比較困難。
  調試麻煩,SQL語言的處理功能簡單。

  總之復雜的操作或需要事務操作的SQL建議使用存儲過程,而參數多且操作簡單SQL語句不建議使用存儲過程。


存儲過程定義

  存儲過程是一組 Transact-SQL 語句,它們只需編譯一次,以後即可多次執行。因為 Transact-SQL 語句不需要重新編譯,所以執行存儲過程可以提高性能。
  觸發器是一種特殊的存儲過程,不由用戶直接調用。創建觸發器時,將其定義為在對特定表或列進行特定類型的數據修改時激發。

存儲過程的設計規則

  CREATE PROCEDURE 定義自身可以包括任意數量和類型的 SQL 語句,但以下語句除外。


  不能在存儲過程的任何位置使用這些語句。
   CREATE AGGREGATE、 CREATERULE、CREATE DEFAULT、 CREATESCHEMA、CREATE 或 ALTER FUNCTION、CREATE 或 ALTER TRIGGER、CREATE 或 ALTER PROCEDURE、CREATE 或 ALTER VIEW、SET PARSEONLY、SET SHOWPLAN_ALL、SET SHOWPLAN_TEXT、 SET SHOWPLAN_XML、USE database_name

  其他數據庫對象均可在存儲過程中創建。可以引用在同一存儲過程中創建的對象,只要引用時已經創建了該對象即可。
  可以在存儲過程內引用臨時表。
  如果在存儲過程內創建本地臨時表,則臨時表僅為該存儲過程而存在;退出該存儲過程後,臨時表將消失。
  如果執行的存儲過程將調用另一個存儲過程,則被調用的存儲過程可以訪問由第一個存儲過程創建的所有對象,包括臨時表在內。
  如果執行對遠程 Microsoft SQL Server 2005 實例進行更改的遠程存儲過程,則不能回滾這些更改。遠程存儲過程不參與事務處理。
  存儲過程中的參數的最大數目為 2100。
  存儲過程中的局部變量的最大數目僅受可用內存的限制。
  根據可用內存的不同,存儲過程最大可達 128 MB

實現存儲過程

CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ;number ]
[ { @parameter [ type_schema_name. ] data_type } [ VARYING ] [ = default ] [ [OUT [ PUT ] ] --名稱、類型、默認值、方向
[ ,...n ]
[ WITH <procedure_option> [,...n ]
[ FOR REPLICATION ]
AS
{
<sql_statement> [;][ ...n ] | <method_specifier> } --SQL語句
[;]
<procedure_option> ::=
[ ENCRYPTION ]
[ RECOMPILE ] --運行時編譯
[ EXECUTE_AS_Clause ]
<sql_statement> ::= { [ BEGIN ] statements [ END ] }
<method_specifier> ::= EXTERNALNAME assembly_name.class_name.method_name


執行存儲過程

  使用 Transact-SQL EXECUTE 語句。如果存儲過程是批處理中的第一條語句,那麽不使用 EXECUTE 關鍵字也可以執行存儲過程,使用 sp_procoption 讓SQLSERVER 自動執行存儲過程
sp_procoption [@ProcName = ] ‘procedure‘ , [ @OptionName = ] ‘option‘ , [@OptionValue = ] ‘value‘ --過程的名稱、option 的唯一值為 startup、設置為開啟(true 或 on)還是關閉(false 或 off)。


用TSQL語句編寫存儲過程

一、變量和參數

DECLARE 語句通過以下操作初始化 Transact-SQL 變量:
指定名稱。名稱的第一個字符必須為一個 @。
指定系統提供的或用戶定義的數據類型和長度。對於數值變量還指定精度和小數位數。對於 XML 類型的變量,可以指定一個可選的架構集合。
將值設置為 NULL。
如:DECLARE @MyCounter int
第一次聲明變量時,其值設置為 NULL。若要為變量賦值,請使用 SET 語句。這是為變量賦值的首選方法。也可以通過 SELECT 語句的選擇列表中當前所引用值為變量賦值。
參數用於在存儲過程和函數以及調用存儲過程或函數的應用程序或工具之間交換數據:
輸入參數允許調用方將數據值傳遞到存儲過程或函數。
輸出參數允許存儲過程將數據值或遊標變量傳遞回調用方。用戶定義函數不能指定輸出參數。
每個存儲過程向調用方返回一個整數返回代碼。如果存儲過程沒有顯式設置返回代碼的值,則返回代碼為 0。

二、流程控制語句

1、BEGIN 和 END 語句
BEGIN 和 END 語句用於將多個Transact-SQL 語句組合為一個邏輯塊。在控制流語句必須執行包含兩條或多條 Transact-SQL 語句的語句塊的任何地方,都可以使用 BEGIN 和 END 語句。
如:
IF (@@ERROR <> 0)
BEGIN
SET @ErrorSaveVariable = @@ERROR
PRINT ‘Error encountered, ‘ +
CAST(@ErrorSaveVariable AS VARCHAR(10))
END
2、GOTO 語句
GOTO 語句使 Transact-SQL 批處理的執行跳至標簽。不執行 GOTO 語句和標簽之間的語句。
IF(1=1)
GOTO calculate_salary
print ‘Go on‘ --條件成立則跳過此句。
calculate_salary:
print ‘go to‘
3、IF...ELSE 語句
IF 語句用於條件的測試。得到的控制流取決於是否指定了可選的 ELSE 語句:
if(1=1)
print 1
else if(2=2)
print 2
else if(3=3)
print 3
else
print 0
4、RETURN 語句
RETURN 語句無條件終止查詢、存儲過程或批處理。存儲過程或批處理中 RETURN 語句後面的語句都不執行。當在存儲過程中使用 RETURN 語句時,此語句可以指定返回給調用應用程序、批處理或過程的整數值。如果RETURN 未指定值,則存儲過程返回 0
5、WAITFOR 語句
WAITFOR 語句掛起批處理、存儲過程或事務的執行,直到發生以下情況:
已超過指定的時間間隔。
到達一天中指定的時間。
指定的 RECEIVE 語句至少修改一行或並將其返回到 Service Broker 隊列。
WAITFOR 語句由下列子句之一指定:
DELAY 關鍵字後為 time_to_pass,是指完成 WAITFOR 語句之前等待的時間。完成 WAITFOR 語句之前等待的時間最多為 24 小時。
如:
WAITFOR DELAY ‘00:00:02‘
SELECT EmployeeID FROM Employee;
TIME 關鍵字後為 time_to_execute,指定 WAITFOR 語句完成所用的時間。
GO
BEGIN
WAITFOR TIME ‘22:00‘;
DBCC CHECKALLOC;
END;
GO
RECEIVE 語句子句,從 Service Broker 隊列檢索一條或多條消息。使用 RECEIVE 語句指定 WAITFOR 時,如果當前未顯示任何消息,該語句將等待消息到達隊列。
TIMEOUT 關鍵字後為 timeout,指定Service Broker 等待消息到達隊列的時間長度(毫秒)。可以在 RECEIVE 語句或 GET CONVERSATION GROUP 語句中指定 TIMEOUT。
6、WHILE...BREAK 或 CONTINUE 語句
只要指定的條件為 True 時,WHILE 語句就會重復語句或語句塊。REAK 或 CONTINUE語句通常和WHILE一起使用。BREAK 語句退出最內層的 WHILE 循環,CONTINUE 語句則重新開始 WHILE 循環。

go
declare @Num int
declare @ID int
declare @i int
set @i=1
while(exists(select * from T where Num<5 )) --獲取數量小於5的記錄
begin
select @Num=Num,@ID=ID from T where Num<5 order by ID desc
print Str(@i)+ 編號:‘+Str(@ID)+ 值‘+str(@Num)
update T set Num=Num*2 where ID=@ID
set @i=@i+1
if(@i>3)
break --退出循環

end


7、CASE 語句
CASE 函數用於計算多個條件並為每個條件返回單個值。CASE 函數通常的用途是將代碼或縮寫替換為可讀性更強的值

--用法一:
select ID,
Grade
=Case Num
when 1 then 不及格‘
when 2 then 不及格‘
when 3 then 不及格‘
when 4 then 良好‘
else 優秀‘
end
from T
---用法二:
select ID,
Grade
=Case
when Num<3 then 不及格‘
when Num=3 then 及格‘
when Num=4 then 良好‘
when Num>4 then 優秀‘
end
from T


三、運行時生成語句

Transact-SQL 支持使用下列兩種方法於運行時在 TTransact-SQL 腳本、存儲過程和觸發器中生成 SQL 語句:
使用 sp_executesql 系統存儲過程執行Unicode 字符串。sp_executesql 支持與RAISERROR 語句類似的參數替換。
使用 EXECUTE 語句執行字符串。EXECUTE 語句不支持已執行字符串中的參數替換。

四、處理數據庫引擎錯誤
在 Transact-SQL 中有兩種方式可以獲取錯誤信息:
1、在 TRY...CATCH 構造的 CATCH 塊的作用域內,您可以使用以下系統函數:
ERROR_LINE(),返回出現錯誤的行號。
ERROR_MESSAGE(),返回將返回給應用程序的消息文本。該文本包括為所有可替換參數提供的值,如長度、對象名或時間。
ERROR_NUMBER() 返回錯誤號。
ERROR_PROCEDURE(),返回出現錯誤的存儲過程或觸發器的名稱。如果在存儲過程或觸發器中未出現錯誤,該函數返回 NULL。
ERROR_SEVERITY() 返回嚴重性。
ERROR_STATE(),返回狀態。
2、在執行任何 Transact-SQL 語句之後,您可以立即使用 @@ERROR 函數測試錯誤並檢索錯誤號。
RAISERROR
RAISERROR 用於將與 SQL Server Database Engine 生成的系統錯誤或警告消息使用相同格式的消息返回到應用程序中。
3、PRINT
PRINT 語句用於將消息返回到應用程序。PRINT 采用字符或 Unicode 字符串表達式作為參數,並將字符串作為消息返回到應用程序。

數據庫的存儲過程