如何将多个 SQL 数据列存储到不同的变量 C#

Posted

技术标签:

【中文标题】如何将多个 SQL 数据列存储到不同的变量 C#【英文标题】:How to store multiple SQL data columns into different variables 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 注入 ... 【参考方案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();
            
        
    

【讨论】:

以上是关于如何将多个 SQL 数据列存储到不同的变量 C#的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将多个 SQL 列组合并存储到一个列中

如何根据 c# winforms 中的列日期和名称将 sql 中的数据输入到特定的 datagridview 单元格中

如何合并 SQL Server 中具有映射到通用描述的不同列标题的表?

在vs2012中用c#想从数据库中读取数据并赋值给一个变量该怎么做呢,有三列分别是a,b,c?

使用 c# 将两个数据集中的特定列合并到第三个数据集中的方法

如何将TimeSpan添加到SQL Server中的时间列