1

我在一个大部分代码都是用 PL/SQL 编写的项目中工作。我们需要重构代码以支持 SQL Server(如果将来可能与数据库无关)。他们决定将 PL SQL 代码转换为 ANSI SQL,但出于某种原因,这对我来说听起来不是一个好主意。

您能说说转换为 ANSI 而不是使用 ORM 的优缺点吗?

谢谢

4

2 回答 2

4

问题是 pl/sql 不仅仅是 sql 语句。它具有逻辑、类型、对象、函数、循环等......

因此,虽然您可以将 sql 语句更改为与 ansi 兼容,但过程语言没有这样的动物。

你需要用某种独立的中间件语言重写 plsql,然后你就依赖它了。

此外,不同的数据库处理提交更改和锁定的方式不同,因此在编写代码时,开发人员需要了解这些差异。

于 2014-01-23T15:42:12.183 回答
1

实现供应商不可知(动态)过程逻辑的一种方法是使用第三方产品,如 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 背后的供应商工作。

于 2021-08-25T10:39:31.290 回答