我在一个大部分代码都是用 PL/SQL 编写的项目中工作。我们需要重构代码以支持 SQL Server(如果将来可能与数据库无关)。他们决定将 PL SQL 代码转换为 ANSI SQL,但出于某种原因,这对我来说听起来不是一个好主意。
您能说说转换为 ANSI 而不是使用 ORM 的优缺点吗?
谢谢
我在一个大部分代码都是用 PL/SQL 编写的项目中工作。我们需要重构代码以支持 SQL Server(如果将来可能与数据库无关)。他们决定将 PL SQL 代码转换为 ANSI SQL,但出于某种原因,这对我来说听起来不是一个好主意。
您能说说转换为 ANSI 而不是使用 ORM 的优缺点吗?
谢谢
问题是 pl/sql 不仅仅是 sql 语句。它具有逻辑、类型、对象、函数、循环等......
因此,虽然您可以将 sql 语句更改为与 ansi 兼容,但过程语言没有这样的动物。
你需要用某种独立的中间件语言重写 plsql,然后你就依赖它了。
此外,不同的数据库处理提交更改和锁定的方式不同,因此在编写代码时,开发人员需要了解这些差异。
实现供应商不可知(动态)过程逻辑的一种方法是使用第三方产品,如 jOOQ,您可以在其中编写如下内容:
ctx.begin(
for_(i).in(1, 10).loop(
insertInto(t).columns(c).values(i)
)
).execute();
这将转化为(选择):
-- Db2
BEGIN
DECLARE i integer;
SET i = 1;
WHILE i <= 10 DO
INSERT INTO t (c)
VALUES (i);
SET i = (i + 1);
END WHILE;
END
-- Firebird
EXECUTE BLOCK AS
DECLARE i integer;
BEGIN
:i = 1;
WHILE (:i <= 10) DO BEGIN
INSERT INTO t (c)
VALUES (:i);
:i = (:i + 1);
END
END
-- MariaDB
BEGIN NOT ATOMIC
FOR i IN 1 .. 10 DO
INSERT INTO t (c)
VALUES (i);
END FOR;
END;
-- Oracle
BEGIN
FOR i IN 1 .. 10 LOOP
INSERT INTO t (c)
VALUES (i);
END LOOP;
END;
-- PostgreSQL
DO $$
BEGIN
FOR i IN 1 .. 10 LOOP
INSERT INTO t (c)
VALUES (i);
END LOOP;
END;
$$
-- SQL Server
BEGIN
DECLARE @i int;
BEGIN
SET @i = 1;
WHILE @i <= 10 BEGIN
INSERT INTO t (c)
VALUES (@i);
SET @i = (@i + 1);
END;
END;
END;
您将被限制在 jOOQ 目前支持的最小公分母上,从 jOOQ 3.15 开始,它从 PL/SQL 中删除了一些特性(例如RECORD
类型、TABLE
类型等),但考虑到作为 Oracle 的要求/SQL Server 不可知论,这可能已经足够好了。
免责声明:我为 jOOQ 背后的供应商工作。