MSSQL存儲過程詳解

SQL Server 存儲過程詳解
存儲過程的優缺點

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

  ◆ 缺點:
  存儲過程將給服務器帶來額外的壓力。
   存儲過程多多時維護比較困難。
  移植性差,在升級到不同的數據庫時比較困難。
  調試麻煩,SQL語言的處理功能簡單。
  總之複雜的操作或需要事務操作的SQL建議使用存儲過程,而參數多且操作簡單SQL語句不建議使用存儲過程

存儲過程定義

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

存儲過程的設計規則

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

  不能在存儲過程的任何位置使用這些語句。
  CREATE AGGREGATE、 CREATE RULE、CREATE DEFAULT、 CREATE SCHEMA、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> ::= EXTERNAL NAME 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 字符串表達式作爲參數,並將字符串作爲消息返回到應用程序。

發佈了29 篇原創文章 · 獲贊 8 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章