从命令提示符(不在sqlplus中)编译PLSQL

时间:2010-08-10 08:21:29

标签: oracle plsql compilation command

有没有办法从命令提示符编译plsql而不是打开sqlplus并编写命令或@filename?

我们希望将输出导入文件并解析它以获取我们正在处理的代码审查工具

...谢谢

3 个答案:

答案 0 :(得分:2)

不确定我是否理解你的意思,听起来你只想捕获执行的输出,但无法判断你是否真的意味着你想完全避免使用SQL * Plus。从我的第一次阅读开始,这很简单:

sqlplus -s user/password @filename > outputfile

...但这让我觉得我错过了一些重要的事情。

答案 1 :(得分:1)

不要这么认为,请参阅Pete Finnigan的this presentation了解一些编译器内部情况。 它列出了您可以使用的ANTLR语法file

我还看到过关于PL / SQL的Scala combinator解析器实现的提及。

答案 2 :(得分:0)

如果您只需输出源 - USER_SOURCE。

我做了很多动态生成的包,我编写的代码可以提取,添加额外的代码,并重新编译包。

最简单的就是你需要将CREATE PACKAGE命令包装成动态SQL。

EXECUTE IMMEDIATE 
    'CREATE OR REPLACE PACKAGE myPackageName AS '||pPackageSource;

但是,这意味着您的源只是一个字符串。我使用旧的DBMS_SQL.PARSE方法,该方法可以接受VARCHAR2行数组(dbms_sql.varchar2s)。

示例 - 将源从user_source拉入varchar 2s的代码,然后通过dbms_sql重新编译同一个包。

DECLARE
    lCid INTEGER;
    lError INTEGER;
    lSource dbms_sql.varchar2s;

    FUNCTION fSource(
        pName IN VARCHAR2,
        pType IN VARCHAR2)
    RETURN dbms_sql.varchar2s
    IS
        CURSOR cSource IS
        SELECT  RTRIM(text,CHR(10))
        FROM    user_source
        WHERE   name = pName
        AND     type = pType
        ORDER BY line;
        lSource pp_type.gtyp_ArrayOfSource;
    BEGIN
       OPEN cSource;
       FETCH cSourcee BULK COLLECT INTO lSource;
       CLOSE cSource;
       RETURN lSource;
     END fSource;
BEGIN
    lSource := fSource(pName => 'myPackageName',pType => 'PACKAGE');
    /* Add CREATE or REPLACE to the start of the source */
    lSource(1) := 'CREATE OR REPLACE '||lSource(1);
-- Cannot use EXECUTE IMMEDIATE as this is an ARRAY
    lCid := dbms_sql.OPEN_CURSOR;
    --
    dbms_sql.parse(
       c    => lCid ,
       statement => lSource,
       lb   => 1,
       ub   => p_source.count,
       lfflg    => true,
       language_flag => dbms_sql.v7
   );
   dbms_sql.close_cursor (lCid);
END;

可以很容易地将其更改为从文件,HTTP服务等中提取源代码 - pl / sql代码/数据库可以访问的任何内容。

实际代码包括验证,检查结果是否有效,通过电子邮件发送与user_source中的行匹配的任何错误(来自user_errors)等。

安全

代码需要以安装程序包的权限运行 - 这可能意味着针对具有比执行用户更高权限的用户安装程序包。

如果您这样做,则需要非常小心哪些接口向“普通”数据库用户公开 - 即您不希望创建任何允许普通用户提取或修改包源或权限的内容。

我的方法是为所有服务功能(获取源,安装,动态执行等)创建一个低级别包(对普通用户隐藏),然后创建一个更高级别的包,将一组有限的特定操作暴露给常规用户 - 在您的情况下,这就像暴露'reviewCode'程序。