Sql ServerストアドプロシージャからC#変数に出力パラメーターを返す際に問題が発生しています。私はこれに関する他の投稿をここで読んだだけでなく、他のサイトで読んだことがあり、それを機能させることはできません。ここに私が現在持っているものがあります。現在、私は戻ってくる値を印刷しようとしています。次のコードはnull値を返します。私が返そうとしているのは主キーです。 @@IDENTITY
とSCOPE_INDENTITY()
(つまりSET @NewId = SCOPE_IDENTITY()
)を使用してみました。
ストアドプロシージャ:
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);
}
}
ストアドプロシージャを(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
プロパティが設定されている列が実際にない可能性があります。
ストアドプロシージャを変更する前に、現在のプロシージャの出力を確認してください。 SQL Server Managementで次を実行します。
DECLARE @NewId int
EXEC @return_value = [dbo].[usp_InsertContract]
N'Gary',
@NewId OUTPUT
SELECT @NewId
それが返すものを参照してください。これにより、出力パラメータが満たされない理由のヒントが得られる場合があります。
ストアドプロシージャ.........
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列はID列ではないと思います。
C#コードでは、コマンドにトランザクションを使用しています。トランザクションをコミットするだけで、その後パラメータ値にアクセスすると、値が取得されます。私のために働いた。 :)