【问题标题】:Doesn't work th SqlCommand with multiple queries对多个查询不起作用的 SqlCommand
【发布时间】:2014-09-06 06:30:07
【问题描述】:

使用一个SELECT 查询,代码似乎可以正确添加到列表框中,但是当我添加另一个查询时,列表框不再显示任何内容,而且似乎rdr[3] 不存在(联系人有3列和Numar_contact有一列(不应该是rdr[3]这一列吗?))

string connString = @"database=Agenda_db; Data Source=Marian-PC\SQLEXPRESS; Persist Security Info=false; Integrated Security=SSPI";
SqlConnection conn = new SqlConnection(connString);

try {
   conn.Open();
   SqlCommand cmd = new SqlCommand("SELECT * FROM Contact;"+ "SELECT * FROM Numar_contact", conn)

   SqlDataReader rdr = cmd.ExecuteReader();

   while (rdr.Read())
   {
       listBox1.Items.Add(rdr[0].ToString() + ' ' + rdr[1].ToString() + ' ' + rdr[2].ToString()+' '+ rdr[3].ToString());
   }

   rdr.Close();

【问题讨论】:

  • 你应该知道 rdr[index] 中有什么。你有调试器吗?
  • 您还应该添加using 块以正确处理您的SqlConnectionSqlCommandSqlDataReader
  • 所以Contact 有 3 列,Numar_contact 有 1 列,您期望一个结果有 4 列?正确的?如果是这样,Contact 中的行如何与Numar_contact 中的行相关联?或者你在做交叉申请。请在您的问题中包含这两个表的实际架构。
  • 目前这两个表没有关系;我不能只将一个表中的 3 列与另一个表中的一列放入一个结果中,并且行数相同吗?
  • 如果你不明白如何创建一个 UNION 查询,那么看看这个简单直接的例子stackoverflow.com/questions/13677318/…

标签: c# sql sql-server-express


【解决方案1】:

通过UNION 加入您的查询。按照您现在的方式,它将返回两个结果集。

SELECT [col1], [col2] FROM Contact
UNION ALL
SELECT [col1], [col2] FROM Numar_contact

正如 DJ KRAZE 在评论中指出的那样,将其包装在 sproc 或 TVF 中可能不是一个坏主意。但这也可以。

编辑:

我刚刚通过 cmets 了解到这两个表实际上是不相关的。鉴于此,我很想使用两个 SqlCommands 和两个不同的 foreach 循环。但如果你是这样被卖掉的,

SELECT id_contact, nume_contact, prenume_contact FROM Contact
UNION ALL
SELECT id_contact, numar, NULL FROM Numar_contact

这将对齐两个表中的数据,但如果第二个表没有[prenume_contact],它将选择NULL。我可能在这里混淆了列位置,因为我不太明白这些名称的含义。

编辑 2:

string connString = @"database=Agenda_db; Data Source=Marian-PC\SQLEXPRESS; Persist Security Info=false; Integrated Security=SSPI";
using (SqlConnection conn = new SqlConnection(connString))
{
    try
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand("SELECT * FROM Contact", conn))
        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                listBox1.Items.Add(rdr[0].ToString() + " " + rdr[1].ToString() + " " + rdr[2].ToString());
            }
        }

        using (SqlCommand cmd2 = new SqlCommand("SELECT * FROM Numar_contact", conn))
        using (SqlDataReader rdr2 = cmd.ExecuteReader())
        {
            while (rdr2.Read())
            {
                listBox1.Items.Add(rdr2[0].ToString() + " " + rdr2[1].ToString());
            }
        }
    }
    catch { }
}

编辑 3,感谢 Scott Chamberlain 的洞察:

另一方面,您可能想要执行某种JOIN,最常见的是INNER JOIN。请注意,这与我们之前讨论过的任何操作完全不同。

SELECT Contact.id_contact, Contact.nume_contact, Contact.prenume_contact, Numar_contact.numar
FROM Contact
INNER JOIN Numar_contact on Contact.id_contact = Numar_contact.id_contact

这会将两个表绑定在一起,为每个contact-numar_contact 返回一条记录。同样,这绝对与执行UNION 相同。在选择您想要的之前,请确保您了解其中的区别。

如果您的第二个表包含与第一个表多对一关联的数据,请使用此选项。

【讨论】:

  • 不,它向我显示此错误:“使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询必须在其目标列表中具有相同数量的表达式。” !
  • 如果你真的想要一种干净的方式来运行代码并返回数据为什么不在存储过程中创建和执行它,那么也许你应该显示你声明它不起作用的代码。 . 我知道它也能正常工作,只是在我的服务器上创建并运行了一个简单的测试
  • 这就是为什么我最初的答案包括免责声明,它取决于您的表格布局。我已经更新了它。列出您希望显式检索的列,这应该可以工作。
  • 我不明白!我有 2 张没有关系的表;第一个表有列(id_contact,nume_contact,prenume_contact),第二个表有两列(我只想得到一个)(列是 numar 和 id_contact);我只想列出第一个表中的 3 列和第二个表中的第一列(在两个表中,我只插入了 2 行)
  • 所以您要将两个不相关的表中的数据添加到一个列表框中?那时我可能会把它分成两个SqlCommands,但我会编辑我的答案。
【解决方案2】:

感谢your comment,您要做的是JOIN 桌子。

SELECT Contact.id_contact, nume_contact, prenume_contact, numar
FROM Contact
INNER JOIN Numar_contact on Contact.id_contact = Numar_contact.id_contact

这会将两个表合并为四列,其中 id_contact 在两个表中都匹配。

您可能需要INNER JOINLEFT JOIN,具体取决于您是否希望行仅在第二个表中有项目时显示,或者无论如何都显示并只显示第四列DBNull.Value

【讨论】:

  • 错误消息框:“关键字'JOIN'附近的语法不正确”,关闭消息框后,列表框显示为空。
  • 这意味着你搞砸了你的 sql。我会先让您的查询在 Sql Management Studio 中工作,然后尝试在您的程序中使用它。
【解决方案3】:

是的,你可以。

这里是an example from the MSDN,我已经修改为使用您的代码 - 您需要将阅读器移至Next ResultSet

string connString = @"database=Agenda_db; Data Source=Marian-PC\SQLEXPRESS; Persist Security Info=false; Integrated Security=SSPI";
SqlConnection conn = new SqlConnection(connString);
SqlCommand myCommand = new SqlCommand("SELECT * FROM Contact; SELECT * FROM Numar_contact", conn);
SqlDataReader myReader ;

int RecordCount=0; 

try
{
    myConnection.Open();
    myReader = myCommand.ExecuteReader();

    while (myReader.Read())
    {
        //Write logic to process data for the first result.
         RecordCount = RecordCount + 1;
    }
    MessageBox.Show("Total number of Contacts: " + RecordCount.ToString());

    bool moreResults = myReader.NextResult();   // <<<<<<<<<<< MOVE TO NEXT RESULTSET

    RecordCount = 0;

    while (moreResults && myReader.Read())
    {
        //Write logic to process data for the second result.
        RecordCount = RecordCount + 1;
    }
    MessageBox.Show("Total number from Numar_contacts: " + RecordCount.ToString());
}
catch(Exception ex) 
{
   MessageBox.Show(ex.ToString());
}
finally
{
    conn.Close(); // Could be replaced with  using statement too
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-26
    • 2013-12-19
    • 2015-09-06
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多