问题
I am developing an application that will use firebird embedded and/or postgres depending on user sophistication. The argument for firebird embedded is that there should be less installation, firewall, UAC, etc issues. So far postgres is like walking on clouds but I have hit a roadblock with firebird. The app is .net and I am using this provider http://www.firebirdsql.org/en/net-provider/ version 3.0.2
Everything technically works but with firebird embedded I am inserting only around 100 records per second whereas with postgres it's over 3000 per second! With postgres I launch a large amount of INSERT INTO... statements as one command and it's fine. For firebird it's not going well. Here is what does work (slowly)
String query = @"INSERT INTO Customers(ID, Name, SiteID) VALUES(1,'delta',2);
INSERT INTO Customers(ID, Name, SiteID) VALUES(2,'phoenix',2);
";
FbScript fbs = new FbScript(query);
fbs.Parse();
FbConnection fbc = new FbConnection(ConnectionString);
FbBatchExecution fbe = new FbBatchExecution(fbc, fbs);
fbe.Execute(true);
However, I am trying to do without the parse. Something similar to the second answer here Run multiple insert queries against firebird database using isql or here http://www.firebirdfaq.org/faq336/
String sql = @"set term ^ ;
EXECUTE BLOCK AS BEGIN
INSERT INTO Customers(ID, Name, SiteID) VALUES(1,'delta',2);
INSERT INTO Customers(ID, Name, SiteID) VALUES(2,'phoenix',2);
end^";
FbCommand cmd = new FbCommand();
PrepareCommand(cmd, connection, (FbTransaction)null, CommandType.Text, sql, commandParameters, out mustCloseConnection);
cmd.ExecuteNonQuery();
With this I get the exception
Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 5
term
Is the first way the only way? It's so slow :(
回答1:
You don't need the set term
statements, these are isql
specific thing. So try
String sql = @"EXECUTE BLOCK AS BEGIN
INSERT INTO Customers(ID, Name, SiteID) VALUES(1,'delta',2);
INSERT INTO Customers(ID, Name, SiteID) VALUES(2,'phoenix',2);
END";
回答2:
Ain already gave an answer on how to fix this, but as an explanation: commandline tools like isql need to know when a statement is complete and can be executed. They use ;
as the terminator. However inside PSQL blocks (stored procedures and EXECUTE BLOCK
, the ;
is also a statement terminator.
To keep the isql tool from sending an incomplete statement to the server (thus causing a parser error), the command SET TERM
exists to switch the statement terminator of the command line (isql). Now isql isn't the only one that uses SET TERM
, for example flamerobin supports it as well.
With drivers like the Firebird .NET provider and its FbCommand
object, you are executing a single statement so there is no need for statement terminators (nor are they supported by Firebird server), therefor SET TERM
is not necessary nor supported.
来源:https://stackoverflow.com/questions/17882366/firebird-embedded-multiple-inserts-using-net-provider