我有一个紧急工作,要在 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 的可靠方法。