如何从多个SELECT语句获取数据并将其存储在DataSet中

时间:2019-04-03 10:18:43

标签: c# firebird

我正在尝试执行多个SELECT语句,例如

DataSet ds = new DataSet();

string sql = @"SELECT * FROM CUSTOMERS;
               SELECT * FROM CUSTOMERS WHERE AGE > 40;";

using (FbConnection connection = new FbConnection(ConectionString))
{
    try
    {
        using (FbCommand cmd = connection.CreateCommand())
        using (FbDataAdapter sda = new FbDataAdapter(cmd))
        {
            cmd.CommandText = sql;
            cmd.CommandType = CommandType.Text;
            connection.Open();
            sda.Fill(ds);
        }
    }
    catch (FbException e)
    {
        Error = e.Message;
    }
    finally
    {
        connection.Close();
    }
}

return ds;

上面的代码对于一个SELECT语句非常有效,但是当有多个SELECT语句时,它将引发异常。

Dynamic SQL Error
SQL error code = -104
Token unknown - line 2, column 1
SELECT

我也尝试过FbBatchExecution,但是我不知道如何从中获取返回的数据。当使用多个INSERT或DELETE语句时,它会很好地工作。

3 个答案:

答案 0 :(得分:1)

与SQL Server相反,Firebird不支持在单个执行中执行多个语句,单个执行也不可以产生多个结果集。如果要执行多个语句,则需要分别执行。

您也不能使用FbBatchExecution,因为那是用于执行插入,更新,删除等(不产生结果集的语句)。

答案 1 :(得分:0)

您必须使用SQL UNION运算符在这两个查询中构建一个查询

请注意,这些查询如何获取相同的行:第一个查询具有第二个查询的所有行以及更多的行

 SELECT * FROM CUSTOMERS;
 SELECT * FROM CUSTOMERS WHERE AGE > 40;

基本上,您可以通过两种方式将它们链接在一起

 SELECT * FROM CUSTOMERS
     UNION ALL
 SELECT * FROM CUSTOMERS WHERE AGE > 40

 SELECT * FROM CUSTOMERS
     UNION DISTINCT
 SELECT * FROM CUSTOMERS WHERE AGE > 40

第一种选择是将一个查询链接到另一个查询,而不必关心它们带来的数据。而且,除非您添加ORDER BY子句,否则它很可能还会保留顺序查询产生的行的顺序,只是因为这样做更容易。但是,无论是SQL标准还是Firebird文档都没有保证,换句话说,这完全是“实现细节”,并且即使将来UNION ALL,也有可能对行进行重新排序以交错查询ORDER BY链接(例如,如果子查询将生成到不同的处理器中进行并行化)。

第二个选项将对临时缓冲区中的输出进行排序,并排除重复项,这将意味着服务器需要更多的工作时间,以及用于该临时缓冲区和排序的内存和/或磁盘中的更多卷,但将确保您没有行中重复(这意味着您的特定查询将与单独的第一个查询具有相同的数据集)。

答案 2 :(得分:0)

我不知道FbConnection提供程序,但是如果实现IDbConnection,那么您可以使用Dapper,然后您的问题可以解决此问题: https://dapper-tutorial.net/querymultiple

string sql = "SELECT * FROM Invoice WHERE InvoiceID = @InvoiceID; SELECT * FROM InvoiceItem WHERE InvoiceID = @InvoiceID;";

using (var connection = My.ConnectionFactory())
{
    connection.Open();

    using (var multi = connection.QueryMultiple(sql, new {InvoiceID = 1}))
    {
        var invoice = multi.Read<Invoice>().First();
        var invoiceItems = multi.Read<InvoiceItem>().ToList();
    }
}