Question

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 :(

Was it helpful?

Solution

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";

OTHER TIPS

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 FbCommandobject, 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top