web-dev-qa-db-ja.com

ADO.NETのストアドプロシージャからの戻り値の取得

ほぼ同じタイトルの別の質問があることは知っていますが、私の質問には答えられません。挿入後に一意の識別子(@@ 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;
21
WebMonster

私の箱を試してみましたが、これは私にとってはうまくいきます:

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);
            }
        }
30
Florian Reischl

私は問題を解決しました:SqlCommand.CommandTypeCommandType.StoredProcedure戻り値や出力パラメータを取得するため。それに関するドキュメントは見つかりませんでしたが、今ではすべてが機能します。

5
WebMonster

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に焦点を合わせているのか)。

4
Marc Gravell

一部の人は、この単純で短い方法を使用して、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
1
Prashant Gupta

以前の通常のクエリで使用する標準的な方法を使用できますが、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();
0
dreamafon