【问题标题】:How to store multiple SQL data columns into different variables C#如何将多个 SQL 数据列存储到不同的变量 C#
【发布时间】:2021-11-14 22:59:29
【问题描述】:

我正在尝试将用于凭证 ID 和凭证金额的 sql 数据存储到一个变量中,并通过单击按钮将其显示到标签中。

protected void Button1_Click(object sender, EventArgs e)
{
    string voucherId = String.Empty;
    string voucherAmount = String.Empty;

    string queryVoucherId = "select voucherid from ReturnForm where email = '" + Session["username"] + "';";
    string queryVoucherAmount = "select voucheramount from ReturnForm where email = '" + Session["username"] + "';";

    int index = 0;

    using (SqlConnection con = new SqlConnection(str))
    {
        SqlCommand cmd = new SqlCommand(queryVoucherId, con);

        con.Open();

        SqlDataReader reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            voucherId = reader[index].ToString();
            index++;
        }
    }

    using (SqlConnection con = new SqlConnection(str))
    {
        SqlCommand cmd = new SqlCommand(queryVoucherAmount, con);
        con.Open();
        SqlDataReader reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            voucherAmount = reader[index].ToString();
            index++;
        }
    }

    if (txtVoucher.Text == voucherId)
    {
        Label3.Visible = true;
        Label3.Text = voucherAmount;
    }
}

当我点击按钮时,它给我一个错误,提示索引超出范围。

【问题讨论】:

  • 开始第二次查询时需要将index重置为0
  • 首先 - 您可以在 single 查询中执行此操作,方法是在 SELECT 语句中选择两个必需的列。更重要的是:永远不要这样写 SQL!不要将您的 SQL 代码与参数值连接在一起 - 使用 参数化查询 - 总是 - 没有例外。您对 #1 Internet 漏洞持开放态度 - SQL 注入 ...

标签: c# asp.net sql-server webforms


【解决方案1】:

以@JSGarcia 的回答为基础——但使用参数作为一个总是应该——你会得到这个代码:

string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom WHERE Email = @email";

DataTable dt = new DataTable();

using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
    // set the parameter before opening connection
    // this also defines the type and length of parameter - just a guess here, might need to change this
    cmd.Parameters.Add("@email", SqlDbType.VarChar, 100).Value = email;

    conn.Open();
    sda.Fill(dt);
    conn.Close();
}

就个人而言,我宁愿使用类似的数据类

public class VoucherData
{
    public int Id { get; set; }
    public Decimal Amount { get; set; }
}

然后从您的 SQL 查询中取回 List<VoucherData>(使用例如 Dapper):

string query = $"SELECT Id, Amount FROM ReturnFrom WHERE Email = @email";

List<VoucherData> vouchers = conn.Query<VoucherData>(query).ToList();

我会尽量避免使用相当笨重且不太容易使用的DataTable 构造...

【讨论】:

    【解决方案2】:

    我强烈建议将您的 sql 查询合并为一个,将其写入数据表并从那里继续您的逻辑。恕我直言,代码更简洁:

    string email = Session['username'];
    string query = $"SELECT voucherid, voucheramount FROM ReturnFrom where Email = '{email}'";
    
    DataTable dt = new DataTable();
    
    using (SqlConnection conn = new SqlConnection(connectionString))
    using (SqlCommand cmd = conn.CreateCommand())
    using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
    {
        cmd.CommandText = query;
        cmd.CommandType = CommandType.Text;
        conn.Open();
        sda.Fill(dt);
        conn.Close();
    }
    
    // Work with DataTable dt from here on
    ...
    

    【讨论】:

    • 但是 - 永远不要这样写SQL!不要将您的 SQL 代码与参数值连接在一起 - 使用 参数化查询 - 总是 - 没有例外。您对 #1 Internet 漏洞持开放态度 - SQL 注入 ...
    • @marc_s 你能编辑我的答案来演示参数化查询吗?
    【解决方案3】:

    好吧,还有一个大提示? 如果您要更新数据表,您通常只需要一个数据适配器。

    如果你说不使用 sql 命令对象,你只需要一个新的连接对象。

    sqlcommand 对象有:

    a connection object - no need to create a separate one
    a reader - no need to create a separate one.
    

    请注意,我没有创建单独的连接对象,而是使用了命令对象中内置的连接对象。

    既然参数在两种情况下都是相同的?那为什么不重用它呢!!

    所以,我们得到了这个:

        void TestFun2()
        {
            String str = "some conneciton???";
    
            DataTable rstVouch = new DataTable();
            using (SqlCommand cmdSQL =
                  new SqlCommand("select voucherid from ReturnForm where email = @email",
                  new SqlConnection(str)))
            {
                cmdSQL.Parameters.Add("@email", SqlDbType.NVarChar).Value = Session["username"];
                cmdSQL.Connection.Open();
    
                rstVouch.Load(cmdSQL.ExecuteReader());
    
                // now get vouch amount
                cmdSQL.CommandText = "select voucheramount from ReturnForm where email = @email";
    
                DataTable rstVouchAmount = new DataTable();
                rstVouchAmount.Load(cmdSQL.ExecuteReader());
    
                if (rstVouch.Rows[0]["vourcherid"].ToString() == txtVoucher.Text)
                {
                    Label3.Visible = true;
                    Label3.Text = rstVouchAmount.Rows[0]["voucheramount"].ToString();
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-29
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多