【问题标题】:How to include PostgreSQL-specific code within portable SQL?如何在可移植 SQL 中包含特定于 PostgreSQL 的代码?
【发布时间】:2011-08-01 15:27:41
【问题描述】:

在 MySQL 中,可以使用特定的注释语法在通用/标准 SQL 中包含 MySQL 特定的 SQL 语句,如下所示:

INSERT /*! DELAYED */ INTO foo VALUES (1, 2, 3);

http://dev.mysql.com/doc/refman/5.1/en/comments.html 对此进行了描述。

是否有任何等效的语法或技巧可用于 PostgreSQL 以将特定于 PostgreSQL 的语句嵌入同一文件中?

我想让我的应用程序在两个平台上都可移植,但在某些情况下,我找不到通用的做事方式,需要做特定于数据库的事情。例如,在这些数据库引擎上将自动递增的列放入表中是完全不同的,但数据库模式的大多数其他部分完全相同并且可以共享。因此,我宁愿在发行版中只包含一个 create-the-database.sql 文件,因为它更易于维护且感觉更整洁。

【问题讨论】:

    标签: sql postgresql syntax portability


    【解决方案1】:

    收起它并创建一个“postgresql.sql”文件和一个“mysql.sql”文件。这需要很少的努力。你可以使用老式的 cpp(1),这样两个模式都在同一个文件中,甚至是交错的。

    % cat foo.sql
    #ifdef USE_POSTGRESQL
    CREATE TABLE pg_epicness (
      -- PostgreSQL schema def
    );
    #elif USE_MYSQL
    CREATE TABLE phail (
      -- idontcareaboutmyusers schema def
    );
    #endif
    % cat foo.sql | cpp -DUSE_POSTGRESQL | grep -v ^# > postgresql.sql
    % cat foo.sql | cpp -DUSE_MYSQL | grep -v ^# > mysql.sql
    

    不漂亮,但正如你所说,你正在寻找一个黑客。由于 .sql 文件中不应该有任何前导的井号字符,因此它是“安全的”。

    【讨论】:

      【解决方案2】:

      我的第一个想法是在编译代码时包含一个预处理步骤,然后可以分别为每个数据库生成一个中间层。然后,您可以分配要使用的任何一个,或者在应用程序中设置一个允许它在两者之间切换的设置。

      您需要对每个平台进行单独的测试,但我还是希望如此。

      预处理器可以像智能搜索和替换一样简单,也可以更复杂。

      【讨论】:

      • 谢谢!除了使用单独的预处理器之外,似乎没有其他明智的方法可以做到这一点。我选择这个答案作为我接受的答案,因为它是建议使用单独预处理器的几个答案中的第一个。
      【解决方案3】:

      如果句法差异在结构上足够兼容,您可能可以使用宏扩展。 M4 是一种流行的便携式宏处理器。我已经在几种不支持宏处理的语言中使用了它,包括 SQL。

      【讨论】:

        【解决方案4】:

        我不知道 Postgres 中的等效功能。无论如何,这种语法是非常有限的:它只适用于“额外”而不是“不同”的东西。

        我知道的唯一方法是使用代码。例如,编写一个函数来创建您的 INSERT 语句。该函数有两个版本:一个用于 Postgres,另一个用于 MySQL。在函数中嵌入任何差异。然后在运行时设置一个标志或有一个工厂来创建适当的子类或其他任何东西来执行正确的函数集。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-25
          • 1970-01-01
          • 1970-01-01
          • 2014-04-24
          • 1970-01-01
          相关资源
          最近更新 更多