You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从存储过程获取表索引并在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:注册成功提示不显示的解决

核心原因

  1. 结果集访问逻辑错误:注册成功时,存储过程只返回一个名为ERRORSuccess的结果集(对应DataSet的Tables[0]),但后台代码先尝试访问ds.Tables[1].Rows[0]["ERRORMsg"],此时DataSet中不存在Tables[1],会抛出异常,导致后续的alert代码无法执行。
  2. 参数添加方式错误:AddWithValue的用法有误,第二个参数应该是参数值,而非SqlDbType枚举,错误的写法会导致参数类型推断异常。
  3. 存储过程变量名笔误:存储过程中使用@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集合会按存储过程返回结果集的顺序依次存储:

  1. 结果集顺序对应Table索引:存储过程中第一个select语句返回的结果集对应ds.Tables[0],第二个对应ds.Tables[1],以此类推。
  2. 安全判断结果集:由于存储过程在不同分支返回不同结构的结果集,建议通过检查Table的Columns集合来判断当前返回的是哪种结果(比如检查是否包含ERRORSuccess或ERRORMsg列),避免直接通过索引访问导致的越界错误。
  3. 优化建议:统一结果集结构
    可以修改存储过程,返回统一结构的结果集,添加状态标识位,让后台代码更易维护:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:50:21