求当前文章的上一篇文章ID存储过程代码:alter proc GetNextArticleIDByID
(
@ID int
)
as
begin
declare @i int
set @i=(select count(*) from Articles where ArticleID<=@ID)
select ArticleID
from (select rn=row_number() over (order by ReleaseDate),* 
from Articles
  )k
where rn=@i-1
end调用存储过程代码    ///<summary>
        /// 读取后一页函数
        ///</summary>
        public int GetNextArticleIDByID(int articleID)
        {
            using (SqlConnection cn = new SqlConnection(this._connectionString))
            {
                SqlCommand cmd = new SqlCommand("GetNextArticleIDByID", cn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(@ID, SqlDbType.Int).Value = articleID;
                cn.Open();
                return (int)ExecuteScalar(cmd);
            }
        }        #region 读取单条记录
        protected object ExecuteScalar(SqlCommand cmd)
        {
            return cmd.ExecuteScalar();
        }
        #endregion结果出现错误:
当前上下文不存在ID.
cmd.Parameters.Add(@ID, SqlDbType.Int).Value = articleID;
调试中红色部分显示调试错误波浪线.

解决方案 »

  1.   

    ExecuteScalar: 它返回的也是单个值,但该返回值是从数据库中读出来的,而不是受影响的行数。它常用于选择一个值的SQL语句。如果用SELECT返回多行或多列,则使用该方法仅返回第一行第一列的数据。
    这种方法可以的啊,即使返回多条记录的话,也是仅返回第一行第一列的数据.ExecuteReader: 被用于返回多条记录的SELECT语句。它将返回一个包含查询结果的SqlDataReader。一个SqlDataReader对象是以向前且只读的形式逐个读取并返回结果的。SqlDataReader有利的一面是它是从数据库中取数最快的对象,不利的一面是操作前需要一个已打开连接,在它被关闭之前,无法使用同一个连接执行其它任何数据库操作。但这个可以通过把SqlDataReader读取的所有记录存入DataTable对象中解决。
    DataTabler 的父类是DataSet,它是一个非常强大的对象,它像一个“内存中”的数据库。DataSet能存储数据表、它们的数据类型、表间的关系等。好多教科书中都用它保持数据,但实际上因为它的复杂的性,它会消耗许多的内存,要尽可能的避免使用它。
      

  2.   

    漏了双引号啦:
    cmd.Parameters.Add("@ID", SqlDbType.Int).Value = articleID;