带有 .net 驱动程序的 Firebird - 如果存在则删除 table

Firebird with .net driver - drop table if exists

我是 Firebird 的新手,我正在测试一些东西以检查 Fb 和 SQlite(以及 .net 驱动程序)之间的差异。

我正在尝试删除 table(如果存在),然后创建 table。在 Sqlite 中,我可以通过以下方式做到这一点:

 command.CommandText = @"DROP TABLE IF EXISTS Persons; CREATE TABLE Persons (
    PersonID int,
    LastName text,
    FirstName text,
    Address text,
    City text); ";
    command.ExecuteNonQuery();

但是在 Firebird 中,相同的查询失败了。我读到在 Firebird SQL 中直接使用 IF 是不可能的,所以我尝试使用:

command.CommandText = @"
EXECUTE BLOCK AS 
BEGIN IF EXISTS 
(SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$RELATION_NAME = 'Persons') 
THEN DROP TABLE Persons; END CREATE TABLE Persons (
        PersonID int,
        LastName varchar(255),
        FirstName varchar(255),
        Address varchar(255),
        City varchar(255) 
            ); ";
command.ExecuteNonQuery();

但它也失败并出现以下错误:

Dynamic SQL Error SQL error code = -104 Token unknown - line 1, column 27

你能帮我解决这个问题吗?我试图在网上找到更多可以帮助我的信息,但没有任何运气。

Firebird 的 SQL 语法没有 drop table if exists,而是使用 recreate table. recreate table will try to drop the table if it exists before creating it. The syntax of recreate table is - other than recreate instead of create - the same as create table.

您尝试使用 execute block 失败的原因有两个:

  1. 您不能将两个语句作为一条命令一起执行。如果要执行包含多个语句的脚本,则需要单独执行每个语句或使用 FbScript class 来解析脚本并为您执行单独的语句。
  2. 即使单独执行这些语句,仍然会失败,因为PSQL(execute block中使用的存储过程语言)不允许执行DDL。您可以使用 execute statement 来规避此限制,但最好不要这样做。通过这种方式,您还可以通过在 execute block.
  3. 中使用 execute statement 执行两者来解决前一点

或者,您可以无条件地删除 table 并捕获(并忽略)由此产生的异常。