我在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行\ n \ 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);
我在这里做错了什么? 感谢
答案 0 :(得分: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
请注意,您还必须删除;
答案 1 :(得分:1)
您的查询不符合Firebird语法。驱动程序一次只能执行一个语句(请注意EXECUTE 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();
}
}
}