我有一个存储过程,用于选择并返回年份列表。在sql server中我称之为:
DECLARE @return_value int
EXEC @return_value = [dbo].[TestName]
@del= 0
SELECT 'Return Value' = @return_value
为了收到清单。
我的SP看起来像这样:
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
我想从c#中做同样的事情并传递List中的值。
我正在尝试的是:
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的建议编辑代码我有类似的东西:
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;
}
}
通过添加断点来探索reader
我发现它只包含错误:
Depth = '(reader).Depth' threw an exception of type 'System.InvalidOperationException'
至于Krishna的回答,dtList
是空的,数为0,我不知道如何实施Badhon的建议。
答案 0 :(得分:3)
ExecuteNonQuery()
之所以被称为是因为它用于不会查询数据的内容。你得到的0
是命令改变的行数。
而是使用ExecuteReader()
,您将获得一个SqlDataReader
对象,您可以调用Read()
来遍历行,然后检查每个对象的详细信息。
如果要将其返回到其他方法,请使用ExecuteReader(CommandBehavior.CloseConnection)
,然后在完成后使用Close()
或Dispose()
连接,Close()
或{{1}读者那将关闭连接。
如果你只有一行有一列(或者由于某种原因只关心第一行的第一列,即使有更多),那么Dispose()
是一种方便的方法来获得这个单一的值
答案 1 :(得分:0)
您不应该使用ExecuteNonQuery,而是使用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;
}
答案 2 :(得分:0)
dbo.TestName是否返回表格或值。如果它返回一个表,那么您必须执行DataAdapter或执行DataReader。您应该替换上述声明 如
DataTable dtList=new DataTable();
SqlDataAdapter adapter=new SqlDataAdapter();
adapter.SelectCommand=command;
adapter.Fill(dtList);
然后,您可以遍历数据表并将其添加到列表中
List<Object> listObj=new List<Object>();
foreach(var rows in dtList.Rows)
{
listObj.Add(rows["Column_name"]);
}
我分析了你的查询,并发现了声明
DECLARE @return_value int
EXEC @return_value = [dbo].[TestName]
@del= 0
SELECT 'Return Value' = @return_value
返回多个表。您可以删除最后一个冗余的语句。
SELECT 'Return Value' = @return_value
现在将使用值填充数据表。
如果有效,请告诉我。