c# - 如何使用 c# 在 firebird 中执行事务(或多个 sql 查询)

标签 c# transactions firebird firebird-.net-provider

我尝试了几种方法,包括在 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/

相关文章:

c# - 如何从另一个行列表中选择包含部分值的行?

sql - 有条件的 where 子句导致 Firebird 的性能很差

C# 如何创建 while 循环来验证对象是否为 null

c# - 在 C# 中为新用户创建环境变量

c# - 可以使用C# codeDOM回调预编译函数吗?

node.js - Google Cloud 数据存储事务实现

mysql - C# 插入所有行还是不插入?

c# - 使用智能在 c# 中取缔字符串

java - 确保事务的 ACID 属性的责任在哪里?

firebird - 无法使用Gsec更改sysdba密码