如何在Oracle存储过程中重命名变量?

时间:2018-12-12 14:57:53

标签: c# oracle stored-procedures plsql

我需要一种方法来重命名大量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#编写一个编辑/替换过程,以将这些存储过程转换为可运行的内联脚本。

1 个答案:

答案 0 :(得分:2)

这样的代码是不好的做法:

WHERE C.COMPANYID=COMPANYID

显然,编写该文档的开发人员认为,显然COMPANYID是没有混叠且没有前缀的,是指相同名称的参数。实际上,编译器将应用范围最接近的匹配标签,即表列名称。因此WHERE子句被解释为

WHERE C.COMPANYID=C.COMPANYID

where 1=1。不好。因此,将参数重命名为独特的东西至关重要。

坏消息是,没有神奇的方法可以做到这一点。您将必须手动编辑每个过程的源。不要在全局搜索和替换操作中使用正则表达式。从您在此处发布的示例中,列引用并非始终是别名,因此无法编写搜索和替换表达式,该表达式可以告诉(例如)COMPANYID中的GROUP BY COMPANYID是列而不是参数。

因此,不幸的是,您需要进行冗长而乏味的工作,查找每次出现的参数名称,确定它实际上是否为参数,然后在适当时对其进行修改。尽量不要花太多时间希望写原始脚本的开发人员遭受发明性的折磨。尽管可能会很有趣,但它会分散注意力,并会导致引入新的错误或丢失现有的错误。

这是一个脚本,您可以使用该脚本来确定任务的范围(假设您具有在其中编译这些过程的架构)。

select package_name
      , object_name as procedure_name
      , argument_name as parameter_name
      , case when length(argument_name) > 28 then '!' end as uh_oh
from user_arguments
where position > 0 -- eliminate function return values
and argument_name in ( select column_name from user_tab_columns )
order by package_name
         , object_name
         , position

user_tab_columns上的子查询是可选的。它仅允许您处理当前麻烦的参数。如果要处理所有参数,请忽略它。

uh_oh属性将标识太长而无法使用简单的P_前缀重命名的参数。您建议的代码建议使用PARAM_作为前缀,但是它不必要地长,并且比两个字符的前缀可能会产生更多的名称更改。