JDBC:调用外部 SQL 脚本,它声明一个 PL/SQL 包

Posted

技术标签:

【中文标题】JDBC:调用外部 SQL 脚本,它声明一个 PL/SQL 包【英文标题】:JDBC: Call external SQL Scripts, which declare a PL/SQL Package 【发布时间】:2015-03-29 03:35:23 【问题描述】:

我有一个名为 setup 的 SQL 脚本,它建立一些设置,然后声明一个名为 salespack 的 PL/SQL 包

setup.sql:

set verify off
set feedback off
set serveroutput on;
set linesize 200;
@Package/pack.sql
@Package/packbody.sql

我有一个名为 main.java 的文件,它尝试运行上述 SQL 脚本,然后调用包,但这似乎不起作用。如何使用jdbc调用SQL脚本,声明PL/SQL包,然后使用包中的函数。我得到的错误是调用stmt.execute();是无效的 SQL 语句。

main.java:

import java.sql.*;
import java.io.*;

class main

  public static void main (String args [])
       throws SQLException, IOException
  
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    String connect = "jdbc:oracle:thin:@vmaddress:1521:xe";
    Connection conn = DriverManager.getConnection (connect, "user", "pass");

    //Perform setup
    //Load packages, allow output, establish sale database
    //Make sure to run the main script from dbSetup to have fresh data
    CallableStatement callstmt = conn.prepareCall ("@setup.sql");
    callstmt.execute();
    callstmt.close();

    CallableStatement callstmt2 = conn.prepareCall (" ? = call salepack.getspname(?) ");
    callstmt2.registerOutParameter (1, Types.VARCHAR);
    int id = 23;    // the id is hard-coded here for simplicity
    callstmt2.setInt(2, id);

    callstmt2.execute();
    String name = callstmt2.getString(1);
    System.out.println ("The salesperson with id of " + id + " is " + name);
    callstmt2.close();
    conn.close();
  

【问题讨论】:

您似乎有一个 SQLPlus 脚本。如果你想使用它,你需要调用 SQLPlus 客户端。我想您可以从您的 Java 应用程序调用 SQLPlus 可执行文件,假设 Java 应用程序运行在安装了完整 Oracle 客户端的机器上。但这将是一个非常奇怪的架构。如果您需要调用 SQLPlus 脚本,那么将其作为应用程序外部安装过程的一部分会更有意义。或者,将代码存储在 Java 应用程序一次可以读取一条语句的位置会更有意义。 您是否正在尝试推出自己的应用程序构建过程? Java 可能是该任务的错误语言。尝试像 Groovy 这样的脚本语言。或者,使用现有的软件包之一,例如 FlyWay(无意或暗示认可)。 【参考方案1】:

我认为您可以使用以下代码运行 setup.sql

private static String script_location = "";
private static String file_extension = ".sql";
private static ProcessBuilder processBuilder =null;

public static void main(String[] args) 
try 
    File file = new File("C:/sql_folder");
    File [] list_files= file.listFiles(new FileFilter() 

        public boolean accept(File f) 
            if (f.getName().toLowerCase().endsWith(file_extension))
                return true;
            return false;
        
    );
    for (int i = 0; i<list_files.length;i++)
        script_location = "@" + list_files[i].getAbsolutePath();//ORACLE
        processBuilder = new ProcessBuilder("sqlplus",        "UserName/Password@database_name", script_location); //ORACLE
        //script_location = "-i" + list_files[i].getAbsolutePath();
        //  processBuilder = new ProcessBuilder("sqlplus", "-Udeep-Pdumbhead-Spc-de-deep\\sqlexpress-de_com",script_location);
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String currentLine = null;
        while ((currentLine = in.readLine()) != null) 
            System.out.println(" "  + currentLine);
        
    
 catch (IOException e) 
    e.printStackTrace();
catch(Exception ex)
    ex.printStackTrace();


也许下面的链接会给你一些其他的想法;

How to display sqlplus result in java?

【讨论】:

以上是关于JDBC:调用外部 SQL 脚本,它声明一个 PL/SQL 包的主要内容,如果未能解决你的问题,请参考以下文章

从 0jdbc6 JDBCthin 驱动程序调用具有自定义对象返回类型的 Oracle PL/SQL 过程

如何通过 JDBC 调用返回 UDO 并解释该结果的 PL/SQL 函数?

是否可以从 jdbc 调用 pl/sql 函数并按名称注册返回值?

带有输入参数的 Oracle JDBC 调用 PL/SQL 过程记录表

带有 PL SQL 表类型参数的 Oracle 存储过程的 JDBC 调用

从 shell 脚本调用 PL/SQL 存储过程并捕获 out 参数