ほぼ同じタイトルの別の質問があることは知っていますが、私の質問には答えられません。挿入後に一意の識別子(@@ identity)を返すストアドプロシージャがあります。サーバーエクスプローラーで試してみましたが、期待どおりに機能します(@RETURN_VALUE = [識別子])。私のコードでは、「@ RETURN_VALUE」と呼ばれるパラメーターを追加しました。他のパラメーターよりもReturnValueの方向が最初ですが、ExecuteNonQuery()でクエリを実行すると、パラメーターは空のままです。何を間違えたかわかりません。私のSPROC:
ALTER PROCEDURE dbo.SetAuction
(
@auctionID int,
@itemID int,
@auctionType tinyint,
@reservationPrice int,
@maxPrice int,
@auctionEnd datetime,
@auctionStart datetime,
@auctionTTL tinyint,
@itemName nchar(50),
@itemDescription nvarchar(MAX),
@categoryID tinyint,
@categoryName nchar(50)
) AS
IF @auctionID <> 0
BEGIN
BEGIN TRAN T1
UPDATE Auction
SET AuctionType = @auctionType,
ReservationPrice = @reservationPrice,
MaxPrice = @maxPrice,
AuctionEnd = @auctionEnd,
AuctionStart = @auctionStart,
AuctionTTL = @auctionTTL
WHERE AuctionID = @auctionID;
UPDATE Item
SET
ItemName = @itemName,
ItemDescription = @itemDescription
WHERE
ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = @auctionID);
COMMIT TRAN T1
RETURN @auctionID
END
ELSE
BEGIN
BEGIN TRAN T1
INSERT INTO Item(ItemName, ItemDescription, CategoryID)
VALUES(@itemName, @itemDescription, @categoryID);
INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL)
VALUES(@@IDENTITY,@auctionType,@reservationPrice,@maxPrice,@auctionEnd,@auctionStart,@auctionTTL);
COMMIT TRAN T1
RETURN @@IDENTITY
END
そして私のコードは:
cmd.CommandText = cmdText;
SqlParameter retval = new SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
cmd.Parameters.AddRange(parameters);
cmd.Connection = connection;
connection.Open();
cmd.ExecuteNonQuery();
return (int)cmd.Parameters["@RETURN_VALUE"].Value;
私の箱を試してみましたが、これは私にとってはうまくいきます:
SQL Serverの場合:
DROP PROCEDURE TestProc;
GO
CREATE PROCEDURE TestProc
AS
RETURN 123;
GO
C#で
string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;";
using (SqlConnection cn = new SqlConnection(cnStr)) {
cn.Open();
using (SqlCommand cmd = new SqlCommand("TestProc", cn)) {
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter returnValue = new SqlParameter();
returnValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(returnValue);
cmd.ExecuteNonQuery();
Assert.AreEqual(123, (int)returnValue.Value);
}
}
私は問題を解決しました:SqlCommand.CommandType
〜CommandType.StoredProcedure
戻り値や出力パラメータを取得するため。それに関するドキュメントは見つかりませんでしたが、今ではすべてが機能します。
TSQLでEXEC
の値を取得できますか? TSQLのリファクタリングが役立つかどうか(そしてSCOPE_IDENTITY()
を使用するかどうか:)
だから変更:
_COMMIT TRAN T1
RETURN @@IDENTITY
_
に:
_SET @auctionID = SCOPE_IDENTITY()
COMMIT TRAN T1
RETURN @auctionID
_
(他の_@@IDENTITY
_もSCOPE_IDENTITY()
に変更します)
小さな最適化として、次のものも使用できます。
_return (int)retval.Value;
_
しかし、物事のこちら側すべき私が見ることができるものから「現状のまま」機能している(したがって、なぜTSQLに焦点を合わせているのか)。
一部の人は、この単純で短い方法を使用して、SPからの戻り値を計算することもできます。
SQLの場合
Create Table TestTable
(
Int Id
)
CREATE PROCEDURE Proc_TestProc
@Id
AS
Begin
Set NOCOUNT ON //Use this line if you don't want to return any message from SQL
Delete from TestTable where Id = @Id
return 1
Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property
End
SQL Serverは常にIntタイプの値のみを返します。
およびC#の場合
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString()))
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Id", 1);
var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
次のコマンドを使用して、SQLの戻り値を確認することもできます。
DECLARE @return_status int;
EXEC @return_status = dbo.[Proc_TestProc] 1;
SELECT 'Return Status' = @return_status;
print 'Returned value from Procedure: ' + Convert(varchar, @return_status); // Either previous or this line both will show you the value of returned value
以前の通常のクエリで使用する標準的な方法を使用できますが、Sqlコマンドでは、ストアプロシージャ名の前にEXECを記述し、次のようなcommandtypeを使用しないでください。
SqlConnection con = new SqlConnection(["ConnectionString"])
SqlCommand com = new SqlCommand("EXEC _Proc @id",con);
com.Parameters.AddWithValue("@id",["IDVALUE"]);
con.Open();
SqlDataReader rdr = com.ExecuteReader();
ArrayList liste = new ArrayList();
While(rdr.Read())
{
liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) ..
}
con.Close();