如何从存储过程获取表索引并在DataSet中访问?注册成功提示异常求助
问题解决:注册成功提示不显示+存储过程结果集在DataSet中的访问
问题描述
创建了AdminRegistration表,调用存储过程LoginRegister时,能收到“用户名已存在”的错误提示,但无法触发“注册成功”的提示。修改表索引后问题仍未解决,同时想了解如何从存储过程返回的结果集中获取对应数据并在DataSet中访问。
相关代码
存储过程代码
ALTER PROCEDURE [dbo].[LoginRegister] @Fname varchar(50), @Email varchar(50), @Username nvarchar(50), @Password nvarchar(50) AS BEGIN SET NOCOUNT ON; Declare @ERROR varchar(100) --checking username not exist or not if not exists(select * from AdminRegister where Username = @Username) BEGIN Insert into AdminRegister(FName,Email,Username,Password) values (@Fname,@Email,@Username,@Password) SET @ERROR=@UserName+' has registered successfully.' select @ERROR as ERRORSuccess END ElSE BEGIN SET @ERROR=@UserName + ' has already exists.' select @ERROR as ERRORMsg END END
C#后台代码
protected void Register_Click(object sender, EventArgs e) { ValidateEmail(); con.Open(); SqlCommand cmd = new SqlCommand("LoginRegister",con); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@Fname", SqlDbType.VarChar).Value = txtname.Text; cmd.Parameters.AddWithValue("@Email", SqlDbType.VarChar).Value = txtmail.Text; cmd.Parameters.AddWithValue("@Username", SqlDbType.NVarChar).Value = txtusername.Text; cmd.Parameters.AddWithValue("@Password", SqlDbType.NVarChar).Value = txtPassword.Text; DataSet ds = new DataSet(); SqlDataAdapter sda = new SqlDataAdapter(cmd); sda.Fill(ds); con.Close(); Lblmsg.Text= ds.Tables[1].Rows[0].Field<string>("ERRORMsg"); String Result = ds.Tables[0].Rows[0].Field<string>("ERRORSuccess"); Response.Write("<script LANGUAGE='JavaScript' >alert('"+Result+"')</script>"); Clear(); }
问题1:注册成功提示不显示的解决
核心原因
- 结果集访问逻辑错误:注册成功时,存储过程只返回一个名为
ERRORSuccess的结果集(对应DataSet的Tables[0]),但后台代码先尝试访问ds.Tables[1].Rows[0]["ERRORMsg"],此时DataSet中不存在Tables[1],会抛出异常,导致后续的alert代码无法执行。 - 参数添加方式错误:
AddWithValue的用法有误,第二个参数应该是参数值,而非SqlDbType枚举,错误的写法会导致参数类型推断异常。 - 存储过程变量名笔误:存储过程中使用
@UserName,但参数定义是@Username(虽然SQL Server大小写不敏感,但统一命名可避免潜在问题)。
修正方案
修正后的C#代码
protected void Register_Click(object sender, EventArgs e) { ValidateEmail(); using (SqlCommand cmd = new SqlCommand("LoginRegister", con)) { cmd.CommandType = CommandType.StoredProcedure; // 正确添加参数:指定类型和长度,避免类型推断错误 cmd.Parameters.Add("@Fname", SqlDbType.VarChar, 50).Value = txtname.Text; cmd.Parameters.Add("@Email", SqlDbType.VarChar, 50).Value = txtmail.Text; cmd.Parameters.Add("@Username", SqlDbType.NVarChar, 50).Value = txtusername.Text; cmd.Parameters.Add("@Password", SqlDbType.NVarChar, 50).Value = txtPassword.Text; DataSet ds = new DataSet(); SqlDataAdapter sda = new SqlDataAdapter(cmd); sda.Fill(ds); con.Close(); // 判断结果集,避免索引越界 if (ds.Tables.Count > 0) { if (ds.Tables[0].Columns.Contains("ERRORMsg")) { // 用户名已存在的情况 Lblmsg.Text = ds.Tables[0].Rows[0].Field<string>("ERRORMsg"); } else if (ds.Tables[0].Columns.Contains("ERRORSuccess")) { // 注册成功的情况 string Result = ds.Tables[0].Rows[0].Field<string>("ERRORSuccess"); Response.Write($"<script>alert('{Result}')</script>"); Clear(); } } } }
修正后的存储过程(统一变量名)
ALTER PROCEDURE [dbo].[LoginRegister] @Fname varchar(50), @Email varchar(50), @Username nvarchar(50), @Password nvarchar(50) AS BEGIN SET NOCOUNT ON; Declare @ERROR varchar(100) if not exists(select * from AdminRegister where Username = @Username) BEGIN Insert into AdminRegister(FName,Email,Username,Password) values (@Fname,@Email,@Username,@Password) SET @ERROR = @Username + ' has registered successfully.' select @ERROR as ERRORSuccess END ElSE BEGIN SET @ERROR = @Username + ' has already exists.' select @ERROR as ERRORMsg END END
问题2:如何从存储过程获取结果集并在DataSet中访问
DataSet中的Tables集合会按存储过程返回结果集的顺序依次存储:
- 结果集顺序对应Table索引:存储过程中第一个
select语句返回的结果集对应ds.Tables[0],第二个对应ds.Tables[1],以此类推。 - 安全判断结果集:由于存储过程在不同分支返回不同结构的结果集,建议通过检查
Table的Columns集合来判断当前返回的是哪种结果(比如检查是否包含ERRORSuccess或ERRORMsg列),避免直接通过索引访问导致的越界错误。 - 优化建议:统一结果集结构
可以修改存储过程,返回统一结构的结果集,添加状态标识位,让后台代码更易维护:
ALTER PROCEDURE [dbo].[LoginRegister] @Fname varchar(50), @Email varchar(50), @Username nvarchar(50), @Password nvarchar(50) AS BEGIN SET NOCOUNT ON; Declare @Message varchar(100) Declare @IsSuccess bit = 0 if not exists(select * from AdminRegister where Username = @Username) BEGIN Insert into AdminRegister(FName,Email,Username,Password) values (@Fname,@Email,@Username,@Password) @Message = @Username + ' has registered successfully.' @IsSuccess = 1 END ElSE BEGIN @Message = @Username + ' has already exists.' END -- 返回统一结构的结果集 select @IsSuccess as IsSuccess, @Message as Message END
对应的后台代码可简化为:
bool isSuccess = ds.Tables[0].Rows[0].Field<bool>("IsSuccess"); string message = ds.Tables[0].Rows[0].Field<string>("Message"); if (isSuccess) { Response.Write($"<script>alert('{message}')</script>"); Clear(); } else { Lblmsg.Text = message; }
内容的提问来源于stack exchange,提问作者Sai_tamil12
相关产品推荐
相关产品推荐

