【发布时间】:2019-05-13 17:15:53
【问题描述】:
我需要一种方法来重命名大量 Oracle 存储过程中的变量。我看到的问题是存储过程变量名称也是表中的列名称,因此编辑、替换不起作用。
例如,在以下过程中,如何将名为:COMPANYID 的变量替换为 PARAM_COMPANYID?
这样做的重点是,我们工作的地方不提供调用存储过程的能力。我们确实有能力运行 SQL 脚本。目前,当我们运行存储过程时,我们必须手动编辑将所有变量替换为实际值。
CREATE OR REPLACE PROCEDURE SP_TEST(
, COMPANYID IN integer default null
, OUTPUT OUT types.cursor_type
) AS
BEGIN
OPEN OUTPUT FOR
SELECT
COMPANYID
FIRSTNAME,
LASTNAME,
from
(
select distinct
COMPANYID
FIRSTNAME,
LASTNAME
FROM ALL_COMPANYS C
WHERE C.COMPANYID=COMPANYID
) TEMP
where TEMP.COMPANYID = DECODE(COMPANY,0,COMPANYID,NVL(COMPANY,COMPANYID))
GROUP BY
COMPANYID
FIRSTNAME,
LASTNAME;
最终的结果是这样的
CREATE OR REPLACE PROCEDURE SP_TEST(
, PARAM_COMPANYID IN integer default null
, OUTPUT OUT types.cursor_type
) AS
BEGIN
OPEN OUTPUT FOR
SELECT
COMPANYID
FIRSTNAME,
LASTNAME,
from
(
select distinct
COMPANYID
FIRSTNAME,
LASTNAME
FROM ALL_COMPANYS C
WHERE C.COMPANYID=PARAM_COMPANYID
) TEMP
where TEMP.COMPANYID = DECODE(COMPANY,0,COMPANYID,NVL(COMPANY,PARAM_COMPANYID))
GROUP BY
COMPANYID
FIRSTNAME,
LASTNAME;
如果有办法将所有 SQL 参数重命名为最终结果(上图),那么我可以使用 C# 编写一个编辑/替换过程,将这些存储过程转换为可运行的内联脚本。
【问题讨论】:
-
“存储过程变量名也是表中的列名” 是非常糟糕的做法。这种冲突不可避免地会导致结果集出现问题。原始脚本来自哪里?无论如何,我可以理解您为什么要编辑存储过程,但我不明白为什么存储过程的第二个版本绕过了对“调用存储过程的能力”的禁令跨度>
-
说错的时候纠正一下,但是看DECODE函数的参数,连Oracle都分不清COMPANYID是列还是参数?!
-
@Yosh,在解码中,由于范围规则,Oracle 将从查询中获取
companyid。 @Robbieone,您可以将要引用同名过程变量的任何companyid值更改为sp_test.companyid,但是没有算法能够为您决定哪些引用需要更改。 -
@Sentinel 是的,我也是这么想的,但是在“结果”版本中,其中一个是参数,所以初始版本永远不会产生预期的结果......谢谢.
-
我同意 APC。这不是一个好的做法,但我发现我必须处理一些事情。带有 DECODE 语句的行取自我们的一个真实生产过程。我也想知道甲骨文如何知道哪个是哪个。不知何故,Oracle 能够分辨出差异,并且 Oracle 能够以某种方式使用自己的内部算法解析这些 proc。我希望有一种方法可以访问它,但似乎没有。谢谢 APC、Yosh、Sentinel
标签: c# oracle stored-procedures plsql