wake-up-neo.net

Verwenden von Ausgabeparametern für gespeicherte Prozeduren in C #

Ich habe ein Problem mit dem Zurückgeben eines Ausgabeparameters aus einer gespeicherten SQL Server-Prozedur in eine C # -Variable. Ich habe die anderen Beiträge dazu gelesen, nicht nur hier, sondern auch auf anderen Seiten, und ich kann es nicht zum Laufen bringen. Hier ist was ich momentan habe. Momentan versuche ich nur, den Wert zu drucken, der zurückkommt. Der folgende Code gibt einen Nullwert zurück. Was ich versuche zurückzukehren, ist der Primärschlüssel. Ich habe versucht, @@IDENTITY und SCOPE_INDENTITY() (d. H. SET @NewId = SCOPE_IDENTITY()) zu verwenden. 

Gespeicherte Prozedur:

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

Datenbank öffnen:

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;
}

Befehl ausführen:

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);
    }
}
48
Gary

Ich habe Ihre gespeicherte Prozedur leicht geändert (um SCOPE_IDENTITY zu verwenden) und es sieht so aus:

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

    SELECT @NewId = SCOPE_IDENTITY()
END

Ich habe dies versucht und es funktioniert gut (mit dieser modifizierten gespeicherten Prozedur):

// 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();
}

Funktioniert das auch in Ihrer Umgebung? Ich kann nicht sagen, warum Ihr ursprünglicher Code nicht funktioniert - aber wenn ich das hier mache, VS2010 und SQL Server 2008 R2, funktioniert es einfach einwandfrei.

Wenn Sie keinen Wert zurückerhalten, vermute ich, dass Ihre Tabelle Contracts möglicherweise nicht wirklich eine Spalte mit der IDENTITY-Eigenschaft enthält.

104
marc_s

Bevor Sie die gespeicherte Prozedur ändern, überprüfen Sie bitte die Ausgabe Ihrer aktuellen. Führen Sie in der SQL Server-Verwaltung Folgendes aus:

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

Sehen Sie, was es zurückgibt. Dies gibt Ihnen möglicherweise Hinweise, warum Ihr Out-Parameter nicht gefüllt ist.

3
TarasB

Gespeicherte Prozedur.........

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);
    }
}

EDIT: "Ich bekomme immer noch einen DBNull-Wert zurück. Objekt kann nicht von DBNull in andere Typen umgewandelt werden. Ich werde das morgen wieder aufnehmen.

Ich glaube, die Id-Spalte in Ihrer SQL-Tabelle ist keine Identitätsspalte.  

enter image description here

1
Jeremy Thompson

In Ihrem C # -Code verwenden Sie für den Befehl ..__ die Transaktion. Machen Sie die Transaktion einfach fest, und nach dem Zugriff auf Ihren Parameterwert erhalten Sie den Wert . Für mich gearbeitet. :) 

0
Nitin