1. 程式人生 > >MSSQL中儲存過程的可選引數的定義和使用_SQL高亮顯示

MSSQL中儲存過程的可選引數的定義和使用_SQL高亮顯示

編輯日誌:
160508建立
160530優化新增:顯式傳參
160916SQL語句高亮顯示、格式優化

可選引數的存在,可以極大的降低程式碼的重複冗餘。在資料庫開發中,也是如此。現在針對MSSQL中儲存過程的可選引數的定義和使用進行基本的介紹,留作備忘。

>準備工作:

在db_test中建立一張測試表T_test:

USE db_test;
CREATE TABLE dbo.T_test
(
Id  INT  IDENTITY(1,1) NOT NULL
,Name  NVARCHAR(20) NOT NULL
,Sex  BIT  DEFAULT(0)
);

插入一些資料:

INSERT INTO dbo.T_test(Name,Sex)
VALUES(N
'NAME1','1') ,(N'NAME2','0') ,(N'NAME3','1') ,(N'NAME4','0');

查詢測試資料:

SELECT Id,Name,Sex
FROM dbo.T_test;

結果為:


Id Name  Sex
-- ----- ---
1  NAME1 1
2  NAME2 0
3  NAME3 1
4  NAME4 0

>儲存過程

建立一個儲存過程:

IF OBJECT_ID('dbo.usp_test_get_name_by_id','P') IS NOT NULL
DROP PROC dbo.usp_test_get_name_by_id;
GO CREATE PROC dbo.usp_test_get_name_by_id @Name AS NVARCHAR(20) OUTPUT ,@Id AS INT = 1 --DEFAULT VALUE: 1 ,@Sex AS BIT = 1 --DEFAULT VALUE: 1 AS BEGIN SET NOCOUNT ON; SELECT @Name = Name FROM dbo.T_test WHERE Id = @Id AND Sex = @Sex; END GO

對儲存過程進行呼叫:

1)不傳遞ID和Sex

DECLARE @Name NVARCHAR(20
)
; EXEC dbo.usp_test_get_name_by_id @Name OUTPUT; SELECT @Name AS NAME;

結果為:

NAME
-----
NAME1

說明:
可見,當呼叫儲存過程的時候不傳遞ID,則儲存過程會使用(儲存過程)定義時設定的ID的預設值1,Sex預設值為1 。

2)傳遞ID

DECLARE @Name NVARCHAR(20);
EXEC dbo.usp_test_get_name_by_id @Name OUTPUT,'3';

SELECT @Name AS NAME;

結果為:

NAME
-----
NAME3

說明:
當呼叫時傳遞ID,則儲存過程在執行的時候會使用從外部傳遞進來的ID值,因為沒有傳遞進來Sex的值,故使用Sex預設值1進行SQL查詢。

3)顯式傳參【新加160530】

    上面介紹的都屬於"非顯式"傳參,即:所傳引數的位置必須嚴格按照儲存過程定義時的位置進行"安排"。這樣的限制,對於呼叫和後期維護而言是非常噁心的事情,這類似於:在SELECT查詢中使用   *  將所有符合要求的資料返回給呼叫者,而所得資料的欄位順序是隨著查詢時表中欄位的順序來確定的,即:如果後期維護對錶中欄位的順序進行了改變,那麼將會對呼叫者帶來"連鎖反應",這是不能忽視的。

1>查詢Id為3,Sex為1的姓名:

DECLARE @Name NVARCHAR(20);
EXEC dbo.usp_test_get_name_by_id @Name OUTPUT,3,1;

SELECT @Name AS NAME;

查詢結果為:

NAME
-----
NAME3

2>如果呼叫儲存過程時,手抖了一下,3和1的位置顛倒了,那麼查詢結果為:

NAME
-----
NAME1

看!神奇的返回了Id為1的那條資料!雖然這不是我們想要的資料,但這是符合邏輯的。因為MSSQL在匹配引數時,將3轉換為了bit型別,因 3 <> 0 ,所以轉換成bit後的值為1。你可以嘗試換一下其他數。

3>MSSQL中可以進行顯示傳參:

對於上面2>中的情況,使用顯示傳參會非常的爽:

SELECT * FROM dbo.T_test;

DECLARE @Name NVARCHAR(20);
EXEC dbo.usp_test_get_name_by_id 
@Name = @Name OUTPUT
,@Sex = 1
,@Id = 3;


SELECT @Name AS NAME;

查詢結果為:

NAME
-----
NAME3

所以,你可以在呼叫儲存過程時,按照你想要的引數傳遞順序進行編輯,而不是必須嚴格依賴於儲存過程定義(或最新定義)中引數的位置。
這樣,就算後期儲存過程對引數的順序進行了修改,也不會對呼叫有任何的影響!