0

我有一个紧急工作,要在 PostGre 和 Amazon 的 RedShift 上工作的 SQL 产品,并将其移植到 Oracle 上工作。(请注意,“工作”目前并不意味着“最佳”,而是“正确”。)

我们所有的表都是使用 ORM (DBI) 定义的,但我们所有的视图当前都存储为内联 SQL。

我希望有一种相对简单的方法来运行以一种通用的方式封装 SQL,并使用一些现有的工具将其转换为特定方言的 SQL。


简单的例子:

  • SELECT CAST(x AS DECIMAL(16,4)) AS foo FROM bah
    =>
  • SELECT CAST(x AS NUMBER(16,4)) AS foo FROM bah

那很简单。我们在部署时有一个“查找和替换阶段”。SQL 存储为CAST(x AS #DECIMAL#(16,4)),然后我们#DECIMAL#根据部署到的方言替换为新字符串。


令人沮丧的例子:

  • SELECT x % y AS modulo FROM foo
    =>
  • SELECT MOD(x, y) AS modulo FROM foo

和...

  • SELECT x / y AS int_div FROM foo
    =>
  • SELECT trunc(x / y) AS int_div FROM foo


我不是 PERL 专家,所以我正在寻找有关如何进行某种宏扩展的指针。
- SQL 将与字符串中的某种宏表达式一起存储
- 将使用包括“dialect”和“sql”在内的参数调用“处理器”
- “dialect”参数将指示宏扩展的输出

无方言 SQL:SELECT #DIV(x,y)# AS z FROM foo

方言:RedShift
输出:SELECT x / y AS z FROM foo

方言:Oracle11g
输出:SELECT floor(x / y) AS z FROM foo


它需要处理子查询等:

无方言 SQL:SELECT #MOD(x, (SELECT MAX(y) FROM bah))# AS z FROM foo

方言:RedShift
输出:SELECT x % (SELECT MAX(y) FROM bah) AS z FROM foo

方言:Oracle11g
输出:SELECT mod(x, (SELECT MAX(y) FROM bah)) AS z FROM foo


或者任何用于存储“通用”SQL 并能够将其转换为“特定方言”SQL 的可靠方法。

4

1 回答 1

3

您可能会发现SQL::Translator模块对此很有用。

SQL::Translator 是一组 Perl 模块,可将特定于供应商的 SQL 表定义转换为其他格式,例如其他特定于供应商的 SQL、ER 图、文档(POD 和 HTML)、XML 和 Class::DBI 类。

于 2015-01-12T13:52:54.313 回答