我尝试了几种方法,包括在 SO 上。
以下 MYSQL 代码在 Firebird 中不起作用:
CREATE TABLE publications (
INT NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`id`),
filename varchar(500) not null unique,
title varchar(500) DEFAULT NULL,
authors varchar(1000) DEFAULT NULL,
uploader int DEFAULT NULL,
keywords varchar(500) DEFAULT NULL,
rawtext text,
lastmodified timestamp default CURRENT_TIMESTAMP
);
因此,为了在 Firebird 中实现这一点,我正在使用:
CREATE TABLE publications (
id int NOT NULL PRIMARY KEY,
filename varchar(500) NOT NULL UNIQUE,
title varchar(500) DEFAULT NULL,
authors varchar(1000) DEFAULT NULL,
uploader int DEFAULT NULL,
keywords varchar(500) DEFAULT NULL,
rawtext text,
file_data BLOB SUB_TYPE 0,
insertdate timestamp DEFAULT NULL
);
CREATE GENERATOR gen_t1_id;
SET GENERATOR gen_t1_id TO 0;
set term !! ;
CREATE TRIGGER journalInsertionTrigger FOR publications
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_T1_ID, 1);
END!!
set term ; !!
在上面,我得到了错误:
批处理执行中止返回的消息是:Dynamic SQL Error SQL error code = -104 Token unknown - line 13, char 2 CREATE"
当我取消注释 //FbTransaction fbt = Connection.BeginTransaction();
和 //fbt.Commit();
Execute requires the Command object to have a Transaction object when the Connection object assigned to the command is in a pending local transaction. The Transaction property of the Command has not been initialized.
我正在使用以下 C# 代码:
//FbTransaction fbt = Connection.BeginTransaction(); //
FbBatchExecution fbe = new FbBatchExecution( Connection );
fbe.SqlStatements = new System.Collections.Specialized.StringCollection();//.Add( queryString ); // Your string here
fbe.SqlStatements.Add( queryString ); // Your string here
fbe.Execute();
//fbt.Commit();
注意: 设置 set term ; !!
开头的sql代码报错:The type of the SQL statement could not be determined
我该怎么做?
最佳答案
Firebird 只能执行单独的 SQL 语句,大多数 Firebird 驱动程序都遵循相同的规则。您不能像这样立即执行脚本。
Firebird.net 提供程序包含一个实用程序类,用于将脚本拆分为单独的语句。
你需要做类似的事情:
using (var connection = new FbConnection(@"User=sysdba;Password=masterkey;Database=D:\data\db\testdatabase.fdb;DataSource=localhost"))
{
connection.Open();
FbScript script = new FbScript(dbScript);
script.Parse();
FbBatchExecution fbe = new FbBatchExecution(connection);
fbe.AppendSqlStatements(script);
fbe.Execute();
}
请注意,要使您当前的脚本正常工作,您还需要替换:
rawtext text,
与
rawtext BLOB SUB_TYPE TEXT CHARACTER SET UTF8
从技术上讲,您可以省略字符集子句,但除非您为数据库定义了默认字符集,否则您应该指定字符集,否则它将是 NONE
,这可能会导致以后出现问题。
当您使用 FbBatchExecution
时,您不能自己启动事务,因为事务是在 Execute
方法内部处理的。请注意,如果您还想在脚本中插入(或以其他方式修改)数据,则应使用 Execute(true)
,以便立即提交每个 DDL 语句。 Firebird 不允许 DML 在同一事务中使用事务中的 DDL 更改。
SET TERM
的问题是由于 SET TERM
不是 Firebird 语法的一部分。它是 ISQL 和 FlameRobin 等工具使用的语法的一部分,例如 FbScript
。
如果您想单独执行这些语句并控制交易,您可以这样做:
using (var connection = new FbConnection(@"User=sysdba;Password=masterkey;Database=D:\data\db\testdatabase.fdb;DataSource=localhost"))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
using (var command = new FbCommand())
{
command.Connection = connection;
command.Transaction = transaction;
command.CommandText = @"CREATE TABLE publications (
id int NOT NULL PRIMARY KEY,
filename varchar(500) NOT NULL UNIQUE,
title varchar(500) DEFAULT NULL,
authors varchar(1000) DEFAULT NULL,
uploader int DEFAULT NULL,
keywords varchar(500) DEFAULT NULL,
rawtext BLOB SUB_TYPE TEXT CHARACTER SET UTF8,
file_data BLOB SUB_TYPE 0,
insertdate timestamp DEFAULT NULL
)";
command.ExecuteNonQuery();
command.CommandText = "CREATE GENERATOR gen_t1_id";
command.ExecuteNonQuery();
command.CommandText = @"CREATE TRIGGER journalInsertionTrigger FOR publications
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_T1_ID, 1);
END";
command.ExecuteNonQuery();
transaction.Commit();
}
}
关于c# - 如何使用 c# 在 firebird 中执行事务(或多个 sql 查询),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33635825/