2012-06-05 40 views
42

我有一個問題,從Sql Server存儲過程返回一個輸出參數到一個C#變量。我已經閱讀了其他文章,不僅在這裏,而且在其他網站上,我不能得到它的工作。這是我現在擁有的。目前我只是試圖打印回來的價值。以下代碼返回一個空值。我試圖返回的是主鍵。我試過使用@@IDENTITYSCOPE_INDENTITY()(即SET @NewId = SCOPE_IDENTITY())。在C#中使用存儲過程輸出參數

存儲過程:

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7), 

    @NewId int OUTPUT 
AS 
BEGIN 

    INSERT into [dbo].[Contracts] (ContractNumber) 
     VALUES (@ContractNumber) 

    Select @NewId = Id From [dbo].[Contracts] where ContractNumber = @ContractNumber 
END 

打開數據庫:

pvConnectionString = "Server = Desktop-PC\\SQLEXPRESS; Database = PVDatabase; User ID = sa; 
    PASSWORD = *******; Trusted_Connection = True;"; 

try 
{ 
    pvConnection = new SqlConnection(pvConnectionString); 
    pvConnection.Open(); 
} 
catch (Exception e) 
{ 
    databaseError = true; 
} 

執行命令:

pvCommand = new SqlCommand("usp_InsertContract", pvConnection); 

pvCommand.Transaction = pvTransaction; 
pvCommand.CommandType = CommandType.StoredProcedure;  

pvCommand.Parameters.Clear(); 
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); 

SqlParameter pvNewId = new SqlParameter(); 
pvNewId.ParameterName = "@NewId"; 
pvNewId.DbType = DbType.Int32; 
pvNewId.Direction = ParameterDirection.Output; 
pvCommand.Parameters.Add(pvNewId); 

try 
{ 
    sqlRows = pvCommand.ExecuteNonQuery(); 

    if (sqlRows > 0) 
     Debug.Print("New Id Inserted = ", 
      pvCommand.Parameters["@NewId"].Value.ToString()); 
    } 
    catch (Exception e) 
    { 
     Debug.Print("Insert Exception Type: {0}", e.GetType()); 
     Debug.Print(" Message: {0}", e.Message); 
    } 
} 
+1

我也使用SCOPE_IDENTITY()而不是重新查詢同一個表,並且如果你得到'查詢可以返回多個結果'的錯誤,當分配給單個輸出變量。 – JMC

+0

我是否使用set命令來執行此操作?SET NewId = SCOPE_IDENTITY()?我用以下代碼替換了select語句... SET @NewId = SCOPE_IDENTITY()並且仍然收到空值。 – Gary

+0

當然,您可以確認新記錄實際上已插入,對嗎?你可以展示更多的C#代碼(連接的打開,命令的創建等)。 – Steve

回答

1

存儲過程.........

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7) 
AS 
BEGIN 

    INSERT into [dbo].[Contracts] (ContractNumber) 
     VALUES (@ContractNumber) 

    SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY] 
END 

C#

pvCommand.CommandType = CommandType.StoredProcedure; 

pvCommand.Parameters.Clear(); 
pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); 
object uniqueId; 
int id; 
    try 
    { 
    uniqueId = pvCommand.ExecuteScalar(); 
    id = Convert.ToInt32(uniqueId); 
    } 
    catch (Exception e) 
    { 
     Debug.Print(" Message: {0}", e.Message); 
    } 
} 

編輯:「我還是拿回的DBNull值....對象不能從DBNull的被轉換爲其他類型。我明天再來看看。我要到我的其他工作,」

我相信你的SQL表中的ID列不是標識列。

enter image description here

+0

但是,這不回答爲什麼新ID的輸出參數返回null的問題。使用'ExecuteScalar',您可以檢索返回值而不是輸出參數。 –

+0

當我進行此更改時,我也收到以下錯誤...未將對象引用設置爲對象的實例。 – Gary

+0

那是因爲該參數在SQL中稱爲SCOPE_IDENTITY; C#仍在尋找名爲@ContractNumber的參數。 –

82

我稍微修改您的存儲過程(使用SCOPE_IDENTITY),它看起來像這樣:

CREATE PROCEDURE usp_InsertContract 
    @ContractNumber varchar(7), 
    @NewId int OUTPUT 
AS 
BEGIN 
    INSERT INTO [dbo].[Contracts] (ContractNumber) 
    VALUES (@ContractNumber) 

    SELECT @NewId = SCOPE_IDENTITY() 
END 

我想這和它的作品只是罰款(與修改的存儲過程):

// define connection and command, in using blocks to ensure disposal 
using(SqlConnection conn = new SqlConnection(pvConnectionString)) 
using(SqlCommand cmd = new SqlCommand("dbo.usp_InsertContract", conn)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 

    // set up the parameters 
    cmd.Parameters.Add("@ContractNumber", SqlDbType.VarChar, 7); 
    cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output; 

    // set parameter values 
    cmd.Parameters["@ContractNumber"].Value = contractNumber; 

    // open connection and execute stored procedure 
    conn.Open(); 
    cmd.ExecuteNonQuery(); 

    // read output value from @NewId 
    int contractID = Convert.ToInt32(cmd.Parameters["@NewId"].Value); 
    conn.Close(); 
} 

這樣也可以在您的環境中工作嗎?我不能說爲什麼你的原始代碼不會工作 - 但是當我在這裏這樣做,VS2010和SQL Server 2008 R2,它只是完美的工作....

如果你沒有得到一個值 - 那麼我懷疑你的表Contracts可能並沒有真正的IDENTITY屬性。

+3

+1非常感謝您接管! –

+6

謝謝!我很感激你們在回答這個問題時對我們這些年後谷歌搜索的時間。 :-) –

+0

@marc_s如果Varchar輸出的大小未知,那麼如何解決這個問題。 – Gunner

3

在更改存儲過程之前,請檢查當前輸出是什麼。在SQL Server Management中運行以下內容:

DECLARE @NewId int 
EXEC @return_value = [dbo].[usp_InsertContract] 
      N'Gary', 
      @NewId OUTPUT 
SELECT @NewId 

查看返回結果。這可能會給你一些提示,說明你的外部參數沒有被填充。

+0

這只是作爲一個答案,但可能應該是一個評論,但我不能轉換它,因爲多個@字符的用法(甚至國防部被拒絕的權利),我不能編輯它讓它工作。 :) – Kev

0

在您的C#代碼中,您正在使用該命令的事務。 只需提交交易,然後訪問您的參數值,您將獲得該值。 爲我工作。 :)

相關問題