C# 在c上检索存储过程的结果#

C# 在c上检索存储过程的结果#,c#,sql,asp.net,C#,Sql,Asp.net,我有一个存储过程,它选择并返回年份列表。在sql server中,我这样称呼它: DECLARE @return_value int EXEC @return_value = [dbo].[TestName] @del= 0 SELECT 'Return Value' = @return_value USE [TestTable] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE

我有一个存储过程,它选择并返回年份列表。在sql server中,我这样称呼它:

DECLARE @return_value int

EXEC    @return_value = [dbo].[TestName]
        @del= 0

SELECT  'Return Value' = @return_value
USE [TestTable]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[TestName] (@delvarchar(7))

AS
BEGIN

                    SELECT   YEAR(  [added]) AS year FROM [MyTable]


                    GROUP BY  YEAR(  [added]) 
                    ORDER BY  YEAR(  [added])  DESC

END
        public List<string> getYears(string constr, int del)
        {
            using (var conn = new SqlConnection(constr))
            using (var command = new SqlCommand("TestName", conn)
            {
                CommandType = CommandType.StoredProcedure
            })
            {
                command.Parameters.AddWithValue("@del", del);
                List<string> retunvalue = new List<string>();
                conn.Open();

                SqlDataReader reader;
                reader = command.ExecuteReader();
                conn.Close();

                return retunvalue;
            }
        }
以便接收列表

我的SP如下所示:

DECLARE @return_value int

EXEC    @return_value = [dbo].[TestName]
        @del= 0

SELECT  'Return Value' = @return_value
USE [TestTable]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[TestName] (@delvarchar(7))

AS
BEGIN

                    SELECT   YEAR(  [added]) AS year FROM [MyTable]


                    GROUP BY  YEAR(  [added]) 
                    ORDER BY  YEAR(  [added])  DESC

END
        public List<string> getYears(string constr, int del)
        {
            using (var conn = new SqlConnection(constr))
            using (var command = new SqlCommand("TestName", conn)
            {
                CommandType = CommandType.StoredProcedure
            })
            {
                command.Parameters.AddWithValue("@del", del);
                List<string> retunvalue = new List<string>();
                conn.Open();

                SqlDataReader reader;
                reader = command.ExecuteReader();
                conn.Close();

                return retunvalue;
            }
        }
不过,我想从c#中执行同样的操作,并将值传递到列表中

我尝试的是:

using (var conn = new SqlConnection(constr))
using (var command = new SqlCommand("TestName", conn)
{
   CommandType = CommandType.StoredProcedure
})
{
   command.Parameters.AddWithValue("@del", del);
   SqlParameter retval = command.Parameters.Add("@return_value", SqlDbType.VarChar);
   retval.Direction = ParameterDirection.ReturnValue;
   conn.Open();
   command.ExecuteNonQuery();
   int retunvalue = (int)command.Parameters["@return_value"].Value;
   conn.Close();

   return retunvalue;
}
但是,它不返回任何值,而是只返回
0
。我做错了什么?如何在指定的变量中获取列表

按照John Hanna的建议编辑代码我有如下建议:

DECLARE @return_value int

EXEC    @return_value = [dbo].[TestName]
        @del= 0

SELECT  'Return Value' = @return_value
USE [TestTable]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[TestName] (@delvarchar(7))

AS
BEGIN

                    SELECT   YEAR(  [added]) AS year FROM [MyTable]


                    GROUP BY  YEAR(  [added]) 
                    ORDER BY  YEAR(  [added])  DESC

END
        public List<string> getYears(string constr, int del)
        {
            using (var conn = new SqlConnection(constr))
            using (var command = new SqlCommand("TestName", conn)
            {
                CommandType = CommandType.StoredProcedure
            })
            {
                command.Parameters.AddWithValue("@del", del);
                List<string> retunvalue = new List<string>();
                conn.Open();

                SqlDataReader reader;
                reader = command.ExecuteReader();
                conn.Close();

                return retunvalue;
            }
        }
public List getYears(string constr,int del)
{
使用(var conn=new SqlConnection(contr))
使用(var命令=新的SqlCommand(“TestName”,conn)
{
CommandType=CommandType.StoredProcess
})
{
command.Parameters.AddWithValue(“@del”,del);
List retunvalue=新列表();
conn.Open();
SqlDataReader;
reader=command.ExecuteReader();
康涅狄格州关闭();
返回返回值;
}
}
通过添加断点来浏览
阅读器
,我发现它只包含错误:

Depth='(读卡器).Depth'引发了类型为“System.InvalidOperationException”的异常


至于克里希纳的回答,
dtList
是空的,计数为0,我不知道如何实现巴东的建议。

你不应该使用ExecuteOnQuery,而应该使用ExecuteDataSet,如下所示:

public List<DSM_DocPropIdentify> GetDocPropIdentify(string docPropIdentifyID, string action, out string errorNumber)
    {
        errorNumber = string.Empty;
        List<DSM_DocPropIdentify> docPropIdentifyList = new List<DSM_DocPropIdentify>();
        DatabaseProviderFactory factory = new DatabaseProviderFactory();
        SqlDatabase db = factory.CreateDefault() as SqlDatabase;
        using (DbCommand dbCommandWrapper = db.GetStoredProcCommand("GetDocPropIdentify"))
        {
            // Set parameters 
            db.AddInParameter(dbCommandWrapper, "@DocPropIdentifyID", SqlDbType.VarChar, docPropIdentifyID);
            db.AddOutParameter(dbCommandWrapper, spStatusParam, DbType.String, 10);
            // Execute SP.
            DataSet ds = db.ExecuteDataSet(dbCommandWrapper);

            if (!db.GetParameterValue(dbCommandWrapper, spStatusParam).IsNullOrZero())
            {
                // Get the error number, if error occurred.
                errorNumber = db.GetParameterValue(dbCommandWrapper, spStatusParam).PrefixErrorCode();
            }
            else
            {
                if (ds.Tables[0].Rows.Count > 0)
                {
                    DataTable dt1 = ds.Tables[0];
                    docPropIdentifyList = dt1.AsEnumerable().Select(reader => new DSM_DocPropIdentify
                    {
                        DocPropIdentifyID = reader.GetString("DocPropIdentifyID"),
                        DocPropertyID = reader.GetString("DocPropertyID"),
                        DocCategoryID = reader.GetString("DocCategoryID"),
                        DocTypeID = reader.GetString("DocTypeID"),
                        OwnerID = reader.GetString("OwnerID"),
                        IdentificationCode = reader.GetString("IdentificationCode"),
                        IdentificationSL = reader.GetString("IdentificationSL"),
                        AttributeGroup = reader.GetString("AttributeGroup"),
                        IdentificationAttribute = reader.GetString("IdentificationAttribute"),
                        IsRequired = reader.GetInt16("IsRequired"),
                        IsAuto = reader.GetInt16("IsAuto"),
                        SetOn = reader.GetString("SetOn"),
                        SetBy = reader.GetString("SetBy"),
                        ModifiedOn = reader.GetString("ModifiedOn"),
                        ModifiedBy = reader.GetString("ModifiedBy"),
                        Status = reader.GetInt32("Status"),
                        Remarks = reader.GetString("Remarks")
                    }).ToList();
                }
            }
        }
        return docPropIdentifyList;
    }
public List getdocpropidentity(string docpropidentifid、string action、out string errorNumber)
{
errorNumber=string.Empty;
List docpropidentitylist=新列表();
DatabaseProviderFactory=新的DatabaseProviderFactory();
SqlDatabase db=factory.CreateDefault()作为SqlDatabase;
使用(DbCommand dbCommandWrapper=db.GetStoredProcCommand(“getdocpropidentity”))
{
//设置参数
db.AddInParameter(dbCommandWrapper,“@docpropIdentificationId”,SqlDbType.VarChar,docpropIdentificationId);
AddOutParameter(dbCommandWrapper,spStatusParam,DbType.String,10);
//执行SP。
数据集ds=db.ExecuteDataSet(dbCommandWrapper);
如果(!db.GetParameterValue(dbCommandWrapper,spStatusParam).IsNullOrZero())
{
//如果发生错误,请获取错误号。
errorNumber=db.GetParameterValue(dbCommandWrapper,spStatusParam).PrefixErrorCode();
}
其他的
{
如果(ds.Tables[0].Rows.Count>0)
{
DataTableDT1=ds.Tables[0];
docProIdentityList=dt1.AsEnumerable()。选择(读卡器=>new DSM_docProIdentity
{
docPropIdentificationId=reader.GetString(“docPropIdentificationId”),
DocPropertyID=reader.GetString(“DocPropertyID”),
DocCategoryID=reader.GetString(“DocCategoryID”),
DocTypeID=reader.GetString(“DocTypeID”),
OwnerID=reader.GetString(“OwnerID”),
IdentificationCode=reader.GetString(“IdentificationCode”),
IdentificationSL=reader.GetString(“IdentificationSL”),
AttributeGroup=reader.GetString(“AttributeGroup”),
IdentificationAttribute=reader.GetString(“IdentificationAttribute”),
IsRequired=reader.GetInt16(“IsRequired”),
IsAuto=reader.GetInt16(“IsAuto”),
SetOn=reader.GetString(“SetOn”),
SetBy=reader.GetString(“SetBy”),
ModifiedOn=reader.GetString(“ModifiedOn”),
ModifiedBy=reader.GetString(“ModifiedBy”),
Status=reader.GetInt32(“Status”),
备注=reader.GetString(“备注”)
}).ToList();
}
}
}
返回docpropidentitylist;
}

是dbo.TestName返回一个表或值。如果返回一个表,那么您必须执行DataAdapter或DataReader。你应该替换上面的陈述 作为

然后您可以遍历datatable并将其添加到列表中

List<Object> listObj=new List<Object>();
foreach(var rows in dtList.Rows)
{
    listObj.Add(rows["Column_name"]);
}
返回多个表。您可以删除冗余的最后一条语句

SELECT  'Return Value' = @return_value
现在将使用值填充datatable

让我知道这是否有效。

ExecuteNonQuery()
之所以被称为ExecuteNonQuery(),是因为它用于不查询数据的东西。返回的
0
是命令更改的行数

相反,使用
ExecuteReader()
,您将返回一个
SqlDataReader
对象,您可以调用该对象来遍历行,然后检查每个行的详细信息

如果要将其返回到另一个方法,请使用
ExecuteReader(CommandBehavior.CloseConnection)
,然后在完成连接后,使用读取器而不是
Close()
Dispose()
关闭连接,然后读取器将关闭连接


如果只有一行有一列(或者出于某种原因,只关心第一行的第一列,即使有更多列),那么
ExecuteScalar()
是一种只获取单个值的方便方法。

该C#代码对于读取返回值来说看起来是正确的。您应该发布SP,因为问题可能在那里(例如,您可能使用SELECT而不是RETURN返回值)。嗨,Jon,我编辑了我的问题,包括尝试您的建议得到的结果。我的建议也包括调用
Read()
。继续调用
Read()