我正在写一个小的ASP.net C#网页,它一直给我一个错误说明: 位置0没有行。
我可能做错了,但这是我的一些代码:
string SqlQuery = "SELECT * ";
SqlQuery += " FROM main_list";
SqlQuery += " WHERE ID = @FindID";
SqlConnection conn = new SqlConnection("server=???;database=contacts;User
ID=???;Password=???;");
conn.Open();
SqlCommand SqlCmd = new SqlCommand(SqlQuery, conn);
SqlCmd.Parameters.Add("@FindID",searchID);
SqlDataAdapter da = new SqlDataAdapter(SqlCmd);
try {
da.Fill(dt);
fillData(p);
}
catch {
txtId.Text = "ERROR";
}
FillData如下:
protected void fillData(int pos) {
txtId.Text = dt.Rows[pos]["ID"].ToString();
txtCompany.Text = dt.Rows[pos]["Company"].ToString();
txtFirstName.Text = dt.Rows[pos]["First_Name"].ToString();
txtLastName.Text = dt.Rows[pos]["Last_Name"].ToString();
txtAddress1.Text = dt.Rows[pos]["Address1"].ToString();
txtAddress2.Text = dt.Rows[pos]["Address2"].ToString();
txtCity.Text = dt.Rows[pos]["City"].ToString();
txtState.Text = dt.Rows[pos]["State"].ToString();
txtZipCode.Text = dt.Rows[pos]["ZipCode"].ToString();
txtPhoneNum1.Text = dt.Rows[pos]["Phone_Num"].ToString();
txtPhoneNum2.Text = dt.Rows[pos]["Phone_Num2"].ToString();
txtFax.Text = dt.Rows[pos]["Fax_Num"].ToString();
txtEmail.Text = dt.Rows[pos]["Email"].ToString();
txtNotes.Text = dt.Rows[pos]["Notes"].ToString();
txtCategory.Text = dt.Rows[pos]["Category"].ToString();
txtSubCategory.Text = dt.Rows[pos]["SubCategory"].ToString();
txtDateAdded.Text = dt.Rows[pos]["DateAdded"].ToString();
txtDateModified.Text = dt.Rows[0]["DateModified"].ToString();
}
这是错误的调用:
protected void btnPrev_Click(object sender, EventArgs e) {
p--;
lblPage.Text = p.ToString();
fillData(p-1);
}
protected void btnNext_Click(object sender, EventArgs e) {
p++;
lblPage.Text = p.ToString();
fillData(p-1);
}
我试图通过行[0]循环到行[1]或者有多少但是它给了我关于位置0或位置1没有行的错误。它只填充一次然后错误输出。
编辑: 我已经尝试访问已经访问过一行的数据库后返回的第二行。例如:行[0]可以正常访问但是当我尝试读取行[1]时它出错并说它在位置1没有行。我可以修改代码以返回行[1]并且它可以正常工作但是当我尝试访问Rows [0]时它会中断。这就是我将变量(p)传递给fillData以便它只显示Rows值的原因。谢谢!
编辑2:我相信这是因为有一个回发可以擦除数据库检索到的值。有没有办法让数据库条目在回发后保持不变?如果不是,我猜我每次都要查询数据库。
答案 0 :(得分:3)
错误消息表明SQL没有返回任何行。您确定要返回数据。
答案 1 :(得分:1)
当你使用dt.Rows[0]
时,你实际上是在说“拿回第一行,并从中获取一个值。”如果DataTable没有任何行(即你的SQL查询没有返回匹配项),那就像是说“这是一个不包含苹果的盘子。拿第一个苹果然后告诉我它是什么颜色” - 见?没有意义。
在尝试阅读之前,您应该检查是否有任何行...
if(dt.Rows.Count > 0)
{
// do stuff here.
}
答案 2 :(得分:0)
使用Linq和存储过程它更好
datacontext context = new datacontext();
var result = context.MyStoredProc(searchID).FirstOrDefault();
答案 3 :(得分:0)
尝试更改
SqlCmd.Parameters.Add("@FindID",searchID);
到
SqlCmd.Parameters.AddWithValue("@FindID",searchID);
答案 4 :(得分:0)
检查您的数据库查询,确保实际返回行。此外,将查询直接放入代码中也是不好的做法,尤其是在使用参数时。您可能想尝试这样的事情:
private Int32 CallStoredProcedure(Int32 FindId)
{
using (var dt = new DataTable())
{
using (var conn = new SqlConnection(ConnectionString))
{
using (var sqlCmd = new SqlCommand("SEL_StoredProcedure", conn))
{
using (var sda = new SqlDataAdapter(sqlCmd))
{
sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("@FindId", FindId);
sqlCmd.Connection.Open();
sda.Fill(dt);
}
}
}
if (dt.Rows.Count == 1)
return Convert.ToInt32(dt.Rows[0]["ID"]);
else if (dt.Rows.Count > 1)
throw new Exception("Multiple records were found with supplied ID; ID = " + studentId.ToString());
}
return 0;
}
要设置存储过程,请在数据库上运行:
CREATE procedure [dbo].[SEL_StoredProcedure]
@FindId int = null
as
SELECT * FROM main_list where ID = @FindId
答案 5 :(得分:-2)
只需从代码中删除索引标识符:
e.g。
txtId.Text = dt.Rows["ID"].ToString();