我正在尝试执行多个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语句时,它会很好地工作。
答案 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();
}
}