使用 ant 将每个存储过程复制到自己的文件中

发布于 2024-08-07 17:55:22 字数 486 浏览 5 评论 0原文

我希望能够有一个 ant 任务,它可以连接到远程 oracle 实例并将每个存储过程复制到自己的文件中。我知道我可以有一个 ant sql 任务来完成,

SELECT object_type, 
       object_name, 
       dbms_metadata.get_ddl(object_type, object_name) object_ddl 
FROM user_objects
WHERE OBJECT_TYPE in ('INDEX', 'TRIGGER', 'TABLE', 'VIEW', 'PACKAGE', 'FUNCTION', 'PROCEDURE', 'SYNONYM', 'TYPE')  
ORDER BY OBJECT_TYPE, OBJECT_NAME

但这会将结果集全部放入一个文件中,而我想要每个过程一个文件(这是因为我打算随后将它们与 SVN 中的内容进行比较)。

有什么想法吗?

谢谢! 亚历克斯

I want to be able to have an ant task which would connect to a remote oracle instance and copy the stored procedures each into its own file. I know I can have an ant sql task which will do

SELECT object_type, 
       object_name, 
       dbms_metadata.get_ddl(object_type, object_name) object_ddl 
FROM user_objects
WHERE OBJECT_TYPE in ('INDEX', 'TRIGGER', 'TABLE', 'VIEW', 'PACKAGE', 'FUNCTION', 'PROCEDURE', 'SYNONYM', 'TYPE')  
ORDER BY OBJECT_TYPE, OBJECT_NAME

but this will get the result set all into one file, whereas I want a file per each procedure (this is because I intend to subsequently diff them against what's in SVN).

Any ideas?

Thanks!
Alex

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

‘画卷フ 2024-08-14 17:55:22

看起来您已经弄清楚了如何构建 SQL 语句并将结果从数据库服务器传输到您的计算机上最难的部分。

现在就这样做。

  1. 构造SQL语句获取所有
    存储过程名称。
  2. 执行
  3. 使用 antcontrib for 任务
    迭代存储过程名称

以下是迭代的方法:

   <for list="${procnames}" delimeter="..." param="sproc-name">
      <sequential>
        <!-- Construct a new SQL statement to get specific
             stored procedure named @{sproc-name} -->
     </sequential>
   </for>

我有兴趣知道如何执行 SQL 代码并从 ant 连接到数据库,您可以发布您的解决方案吗?

Looks like you've already figured out the hardest part on how to construct SQL statement and get the results from the database server to your machine.

Now do this.

  1. Construct SQL statement to get all
    stored procedure names.
  2. Execute <loadfile
    property="procnames"
    file="result-of-sql-run.txt"/>
  3. Use antcontrib for task to
    iterate over stored procedure names

Here is how to iterate:

   <for list="${procnames}" delimeter="..." param="sproc-name">
      <sequential>
        <!-- Construct a new SQL statement to get specific
             stored procedure named @{sproc-name} -->
     </sequential>
   </for>

I would be interested to know how you execute SQL code and connect to the database from ant, could you publish your solution?

初相遇 2024-08-14 17:55:22

亚历山大,非常感谢你的帮助。这是我根据您的建议使用的代码。唯一的免责声明是,因为我必须执行 dbms_lob.substr 将 clob 转换为 varchar2,所以我可以从每个过程 ddl 中获取的最大字符数是 4000 个字符,而且,它在转换过程中终止了格式化,最终全部变成一行。如果您对如何纠正这两个问题有任何想法,请告诉我。

<target name="retrieve_procedures_names" depends="environment">

    <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
         password="${mp.db.password}" print="yes"
         output="${db.tmp.dir}/procedure_names.txt" onerror="stop" autocommit="true" encoding="UTF-8"
         showheaders="false" showtrailers="false">
        <classpath location="${db.driver.jar}"/>
        SELECT OBJECT_NAME FROM user_objects WHERE OBJECT_TYPE = 'PROCEDURE'
    </sql>

</target>
<target name="retrieve_procedures" depends="retrieve_procedures_names">
    <loadfile property="procnames" srcfile="${db.tmp.dir}/procedure_names.txt"/>
    <for list="${procnames}" delimiter="${line.separator}" param="sproc-name">
        <sequential>
            <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
                 password="${mp.db.password}" print="yes"
                 output="${db.tmp.dir}/@{sproc-name}.txt" onerror="stop" autocommit="true" encoding="UTF-8"
                 keepformat="true" showheaders="false" showtrailers="false">
                <classpath location="${db.driver.jar}"/>
                SELECT dbms_lob.substr(dbms_metadata.get_ddl(object_type, object_name), 4000, 1) FROM user_objects
                WHERE OBJECT_TYPE = 'PROCEDURE' and upper(object_name) = '@{sproc-name}'
            </sql>
        </sequential>
    </for>

</target>

Alexander, thanks so much for your help. Here's the code I used, based on your suggestion. The only disclaimer is that because I had to do dbms_lob.substr to convert the clob to varchar2, the max I could grab is 4000 characters from each procedure ddl and also, it killed the formatting during this conversion and ended all up in one line. If you have any ideas of how to rectify those two issues, let me know.

<target name="retrieve_procedures_names" depends="environment">

    <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
         password="${mp.db.password}" print="yes"
         output="${db.tmp.dir}/procedure_names.txt" onerror="stop" autocommit="true" encoding="UTF-8"
         showheaders="false" showtrailers="false">
        <classpath location="${db.driver.jar}"/>
        SELECT OBJECT_NAME FROM user_objects WHERE OBJECT_TYPE = 'PROCEDURE'
    </sql>

</target>
<target name="retrieve_procedures" depends="retrieve_procedures_names">
    <loadfile property="procnames" srcfile="${db.tmp.dir}/procedure_names.txt"/>
    <for list="${procnames}" delimiter="${line.separator}" param="sproc-name">
        <sequential>
            <sql driver="${mp.db.driver.class}" url="${mp.db.connection.url}" userid="${mp.db.user.name}"
                 password="${mp.db.password}" print="yes"
                 output="${db.tmp.dir}/@{sproc-name}.txt" onerror="stop" autocommit="true" encoding="UTF-8"
                 keepformat="true" showheaders="false" showtrailers="false">
                <classpath location="${db.driver.jar}"/>
                SELECT dbms_lob.substr(dbms_metadata.get_ddl(object_type, object_name), 4000, 1) FROM user_objects
                WHERE OBJECT_TYPE = 'PROCEDURE' and upper(object_name) = '@{sproc-name}'
            </sql>
        </sequential>
    </for>

</target>
叹倦 2024-08-14 17:55:22

我已经做过类似的事情,我建议您用另一种语言(我使用 Perl)编写 DDL 提取器/文件创建器,并使用 Ant exec 任务启动它 - 我知道这有点让人皱眉,但是使用另一种语言比“SELECT DBMS_METADATA.GET_DDL...”方法具有一些优势:(

注意:您将编写的外部程序仍然是 DBMS_METADATA.GET_DDL 的包装器)

  • 您可以以编程方式设置
    DBMS_METADATA.SET_TRANSFORM_PARAM
    为您提供更好匹配的选项
    您的源代码控制标准。

  • 如果需要,您可以删除架构限定符。

  • 如果您的对象最初不是通过源代码管理中的 Ant 部署的,您可以通过执行其他客户端程序可能引入的一些简单的空白转换来减少不匹配噪音。

  • 如果您有该标准,您可以更好地控制您生成的文件的扩展名(例如触发器的“.trg”)。

I've done something similar, and I'd suggest you write the DDL extractor/file creator in another language (I used Perl) and launch it with the Ant exec task - I know this is somewhat frowned upon, but shelling out to another language gives you some advantages over the "SELECT DBMS_METADATA.GET_DDL..." method:

(Note: the external program you'll be writing is still a wrapper around DBMS_METADATA.GET_DDL)

  • You can programatically set the
    DBMS_METADATA.SET_TRANSFORM_PARAM
    options to give you a better match to
    your source control standards.

  • You can strip out schema qualifiers if necessary.

  • If your objects were not originally deployed through Ant from source control you can reduce the mismatch noise by doing some simple whitespace transformations that other client programs may introduce.

  • You can better control the extensions of the files you produce if you have that standard (e.g. ".trg" for triggers).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文