2013-01-17 61 views
3

浏览了一些答案,似乎没有为我工作。C#Scope_Identity问题

我需要一个表的ID字段如此送回我可以在程序的不同部分使用它,我已经使用

Convert.ToInt32(sqlComm.ExecuteScalar()); 

,但没有运气,并同受审

Convert.ToInt32(sqlComm.Parameters["ID"].Value); 

即使记录确实插入到表中,两者都返回0。

我会转储下面的代码,任何人都可以看到我做错了什么?

using (SqlConnection sqlConnect = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)) 
     { 
      using (SqlCommand sqlComm = new SqlCommand("up_Insert_Address", sqlConnect)) 
      { 
       sqlComm.CommandType = CommandType.StoredProcedure; 
       sqlComm.Parameters.Add("@AddressID", SqlDbType.BigInt).Direction = ParameterDirection.Output; 
       sqlComm.Parameters.Add("@AddressLineOne", SqlDbType.NVarChar, 40).Value = address.AddressLineOne; 

       try 
       { 
        sqlComm.Connection.Open(); 
        return Convert.ToInt32(sqlComm.ExecuteScalar()); 
       } 

       catch (SqlException) 
       { 
       } 

       finally 
       { 
        sqlComm.Connection.Close(); 
       } 
      } 
     } 

和存储的过程:

@AddressID Bigint OUTPUT, 
    @AddressLineOne NVarChar(40) 
    AS 
    BEGIN 
     BEGIN TRY 
     INSERT INTO Address 
     (
     AddressLineOne 
    ) 
     VALUES 
     (
     @AddressLineOne 
    ) 

     SET @AddressID = SCOPE_IDENTITY(); 
    END TRY 
    BEGIN CATCH 
     DECLARE @Err nvarchar(500) 
     SET @Err = ERROR_MESSAGE() 
     RAISERROR(@Err, 16, 1) 
    END CATCH 
    END 

回答

6

您应该使用

Convert.ToInt64(sqlComm.Parameters["@AddressID"].Value); 

您执行使用ExceuteNonQuery命令后。为了将来参考,ExecuteScalar返回查询返回的结果集中第一行的第一列。您不会返回任何内容,只需设置OUTPUT参数的值即可。

此外,你应该肯定不会吞下任何SqlException。由于你的命令和连接已经在using块中,所以你不需要再添加try/catch/finally。将其更改为到:

//try 
//{ 
    sqlComm.Connection.Open(); 
    sqlComm.ExecuteNonQuery(); 
    return Convert.ToInt64(sqlComm.Parameters["@AddressID"].Value); 
    // using Int64 since the SQL type is BigInt 
//} 

//catch (SqlException) 
//{ 
//} 

//finally 
//{ 
// sqlComm.Connection.Close(); 
//} 
+0

这个工作。谢谢! – ZeeeeeV

+0

不客气 - 请查看我关于删除“catch”块的更新。 –

+0

我建议在结果('OUTPUT'参数)上使用'long.TryParse()'作为防止引发异常的附加措施。它不应该发生,但如果稍后有人更改模式,这种方式现有的代码将更容错。 – Erik

0
var connectionstring = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; 

var addressId = 0L; // long value (64bit) 

using (var connection = new SqlConnection(connectionString)) 
using (var command = new SqlCommand("up_Insert_Address", connection)) 
{ 
    command.CommandType = CommandType.StoredProcedure; 

    command.Parameters.AddWithValue("@AddressID", addressId);  
    command.Parameters.AddWithValue("@AddressLineOne", address.AddressLineOne); 

    command.Parameters["@AddressID"].Direction = ParameterDirection.Output; 

    try 
    { 
    if(connection.State != ConnectionState.Open) 
     connection.Open(); 

    var rowsAffected = command.ExecuteNonQuery(); 
    addressId = Convert.ToInt64(command.Parameters["@AddressID"].Value); 
    } 
    catch (SqlException) 
    { 
    // Handle SQL errors here. 
    } 
}