首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 存儲過程返回值獲取全攻略:OUTPUT、RETURN 與結果集

     編輯:關於SqlServer

前言

在 SQL Server 開發中,存儲過程是封裝業務邏輯、提升性能的核心手段。而如何正確獲取存儲過程的返回值,則是每位開發者必須掌握的基本功。本文將系統梳理三種主流返回方式——OUTPUT 參數、RETURN 值、結果集——並配合 T-SQL 與 C# 實戰代碼,助你輕鬆應對各類場景。

一、OUTPUT 參數:靈活傳遞多值

OUTPUT 參數是存儲過程對外輸出數據最常用的方式,支持多個輸出參數,類型豐富,適合返回新增記錄的自增 ID、計算結果等。

1. T-SQL 定義與調用

CREATE PROCEDURE [dbo].[nb_order_insert]
    @o_buyerid INT,
    @o_id BIGINT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO [Order](o_buyerid) VALUES (@o_buyerid);
    SET @o_id = @@IDENTITY;  -- 將新生成的自增 ID 回傳
END

調用示例:

DECLARE @o_buyerid INT = 1001;
DECLARE @o_id BIGINT;
EXEC [nb_order_insert] @o_buyerid, @o_id OUTPUT;
SELECT @o_id AS NewOrderId;  -- 獲得剛插入訂單的 ID

2. C# 端接收 OUTPUT 參數

public static decimal GetUserAmount(int uid)
{
    decimal amount = 0;
    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand("Cart_UserAmount", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@UID", uid);
        // 關鍵:Direction = ParameterDirection.Output
        cmd.Parameters.Add("@Amount", SqlDbType.Decimal).Direction = ParameterDirection.Output;

        conn.Open();
        cmd.ExecuteNonQuery();
        amount = (decimal)cmd.Parameters["@Amount"].Value;
    }
    return amount;
}

二、RETURN 值:狀態碼與簡單整數

RETURN 只能返回 INT 類型,通常用於表示執行狀態(如 0 失敗、1 成功)或影響行數。注意:RETURN 會立即結束存儲過程。

1. T-SQL 定義與調用

CREATE PROCEDURE [dbo].[nb_order_insert]
    @o_buyerid INT,
    @o_id BIGINT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    IF EXISTS (SELECT 1 FROM [Shop] WHERE [s_id] = @o_buyerid)
    BEGIN
        INSERT INTO [Order](o_buyerid) VALUES (@o_buyerid);
        SET @o_id = @@IDENTITY;
        RETURN 1;  -- 成功
    END
    ELSE
    BEGIN
        RETURN 0;  -- 失敗:買家不存在
    END
END

調用示例:

DECLARE @o_buyerid INT = 1001;
DECLARE @o_id BIGINT;
DECLARE @result INT;
EXEC @result = [nb_order_insert] @o_buyerid, @o_id OUTPUT;
SELECT @result AS RetCode;  -- 1 或 0

2. C# 端接收 RETURN 值

public static int AddUser(User us)
{
    int retVal = -1;
    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand("User_Add", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        // 輸入參數
        cmd.Parameters.AddWithValue("@UName", us.UName);
        cmd.Parameters.AddWithValue("@UPass", us.UPass);
        // ... 其他參數省略 ...
        // 關鍵:Direction = ParameterDirection.ReturnValue
        cmd.Parameters.Add("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

        conn.Open();
        cmd.ExecuteNonQuery();
        retVal = (int)cmd.Parameters["@RETURN_VALUE"].Value;
    }
    return retVal;
}

三、結果集:返回查詢數據

存儲過程中直接 SELECT 即可返回結果集,適合分頁、報表、列表頁等場景。

1. T-SQL 定義

CREATE PROCEDURE [dbo].[nb_order_select]
    @o_id INT
AS
BEGIN
    SET NOCOUNT ON;
    SELECT o_id, o_buyerid FROM [Order] WHERE o_id = @o_id;
END

2. 臨時表接收結果集(進階技巧)

若需在 T-SQL 中進一步處理結果集,可用 INSERT ... EXEC 配合臨時表:

CREATE TABLE #Temp (
    o_id BIGINT IDENTITY(1,1) NOT NULL,
    o_buyerid INT NOT NULL
);
INSERT #Temp EXEC [nb_order_select] @o_id = 1001;
SELECT * FROM #Temp;
DROP TABLE #Temp;

3. C# 端用 SqlDataAdapter 填充 DataSet

public static DataSet ExecuteSpReturnDataSet(string spName, params SqlParameter[] parameters)
{
    using (var conn = new SqlConnection(ConnStr))
    using (var cmd = new SqlCommand(spName, conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        if (parameters != null) cmd.Parameters.AddRange(parameters);

        var da = new SqlDataAdapter(cmd);
        var ds = new DataSet();
        da.Fill(ds);
        return ds;
    }
}

// 調用
var ds = ExecuteSpReturnDataSet("nb_order_select", new SqlParameter("@o_id", 1001));
var dt = ds.Tables[0];  // 獲得 DataTable

四、核心差異對比表

特性OUTPUT 參數RETURN 值結果集
返回數量多個單個多行多列
數據類型任意標量類型僅 INT任意
適用場景新增 ID、計算值、多值輸出狀態碼、影響行數查詢列表、報表數據
C# 接收方式ParameterDirection.OutputParameterDirection.ReturnValueSqlDataAdapter.Fill / ExecuteReader

五、最佳實踐建議

  1. 優先用 OUTPUT 參數返回業務數據(如新增 ID、統計值),語義清晰且類型安全。
  2. RETURN 僅用於狀態碼(0/1、錯誤代碼),切勿濫用於業務數據。
  3. 結果集用於純查詢,避免在存儲過程中混雜 DML 與 SELECT 導致邏輯混亂。
  4. C# 端務必使用 using 塊確保連接、命令、適配器及時釋放,避免連接泄漏。
  5. 參數化查詢防注入,所有輸入均走 Parameters 集合,絕不拼接 SQL 字符串。

結語

掌握三種返回方式的優劣與適用場景,能讓你的存儲過程設計更專業、調用更高效、維護更輕鬆。實戰中建議結合 OUTPUT + 結果集 的組合:寫操作用 OUTPUT 回傳關鍵標識,讀操作直接返回結果集,RETURN 僅作為執行狀態的「紅綠燈」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved