0

我在 C# 中生成多个插入记录查询并尝试在 FireBird 中执行。

当我在 FlameRobin 上运行它时,它运行良好。但是当我通过 C# 运行它时,它会抛出异常。

SET TERM ^ ; INSERT INTO COUNTRY1 SELECT '2', 'two ' FROM RDB$DATABASE UNION ALL SELECT '4', 'four' FROM RDB$DATABASE UNION ALL SELECT '5', 'five' FROM RDB$DATABASE; ^ SET TERM ; ^ 

C# 代码中的异常是

{"动态 SQL 错误\r\nSQL 错误代码 = -104\r\n令牌未知 - 第 1 行,字符 5\r\nTERM"}

C#代码是

string sQuery = "SET TERM ^ ; INSERT INTO COUNTRY1 SELECT '2', 'two ' FROM RDB$DATABASE UNION ALL SELECT '4', 'four' FROM RDB$DATABASE UNION ALL SELECT '5', 'five' FROM RDB$DATABASE; ^ SET TERM ; ^ ";
SqlHelper.ExecuteNonQuery(SQLHelp.Connectionstring, CommandType.Text, sQuery);

知道我在这里做错了什么吗?谢谢

4

2 回答 2

2

您包含的set term语句不是 Firebird SQL 语言的一部分,而是一种解释器配置指令,首先在isql中引入,它是 Firebird 的命令行客户端。

以这种方式查看您的脚本:

SET TERM ^ ; 

INSERT INTO COUNTRY1 
  SELECT '2', 'two ' FROM RDB$DATABASE 
  UNION ALL SELECT '4', 'four' FROM RDB$DATABASE 
  UNION ALL SELECT '5', 'five' FROM RDB$DATABASE; ^ 

SET TERM ; ^

引擎不知道也无法处理这些set term语句。

FlameRobin 和其他客户端set term为兼容性添加了对语句的支持:允许运行为 isql 编写的 SQL 脚本,或者因为它们缺少完整的 SQL 解析器,并且当脚本包含分号时仍需要正确识别语句的结束位置。但是所有这些客户端,一旦在脚本中分隔语句,就不会将其发送set term到引擎,只是忽略它。

您必须这样做:删除set term语句并发送您拥有的唯一其他语句,如下所示:

INSERT INTO COUNTRY1 
  SELECT '2', 'two ' FROM RDB$DATABASE 
  UNION ALL SELECT '4', 'four' FROM RDB$DATABASE 
  UNION ALL SELECT '5', 'five' FROM RDB$DATABASE

请注意,您还必须删除;

于 2013-04-11T06:34:22.610 回答
1

您的查询不符合 Firebird 语法。驱动程序一次只能执行一条语句(注意 anEXECUTE BLOCK被认为是一条语句)。您不应该使用SET TERM,它是 ISQL 工具(以及其他一些查询工具,如 FlameRobin)的产物,实际上并不是 Firebird SQL 语言的一部分。

您也不应该包含;在查询中。这些仅在 1)PSQL(存储过程、触发器和内部EXECUTE BLOCK)和 2)再次在 ISQL 等工具中有效,以分隔(结束)语句。

因此,单独使用以下查询就足够了:

INSERT INTO COUNTRY1 SELECT '2', 'two ' FROM RDB$DATABASE UNION ALL SELECT '4', 'four' FROM RDB$DATABASE UNION ALL SELECT '5', 'five' FROM RDB$DATABASE

编辑

正如我所评论的,UNION当与INSERT ... SELECT.

使用子选择可能会起作用:

INSERT INTO COUNTRY1 
  SELECT column1, column2 FROM (
     SELECT '2' AS column1, 'two ' AS column2 FROM RDB$DATABASE 
     UNION ALL SELECT '4', 'four' FROM RDB$DATABASE 
     UNION ALL SELECT '5', 'five' FROM RDB$DATABASE
  )

编辑 2

我刚刚使用下面的代码对其进行了测试,它可以工作:插入了预期的行:

static void Main(string[] args)
{
    var constrBuilder = new FbConnectionStringBuilder();
    constrBuilder.DataSource = "localhost";
    constrBuilder.Database = @"D:\data\db\testdatabase.fdb";
    constrBuilder.UserID = "sysdba";
    constrBuilder.Password = "masterkey";

    string constr = constrBuilder.ToString();

    using (var con = new FbConnection(constr))
    {
        con.Open();
        using (var trans = con.BeginTransaction())
        {
            var cmd = new FbCommand();
            cmd.CommandText = "INSERT INTO COUNTRY1 SELECT '2', 'two ' FROM RDB$DATABASE UNION ALL SELECT '4', 'four' FROM RDB$DATABASE UNION ALL SELECT '5', 'five' FROM RDB$DATABASE";
            cmd.Connection = con;
            cmd.Transaction = trans;

            cmd.ExecuteNonQuery();
            trans.Commit();
        }
    }
}
于 2013-04-11T06:34:02.843 回答