Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从groovy调用参数化sql过程_Java_Sql_Groovy - Fatal编程技术网

Java 如何从groovy调用参数化sql过程

Java 如何从groovy调用参数化sql过程,java,sql,groovy,Java,Sql,Groovy,我正在从groovy运行一些过程: sql.call("{call SCHEMA.NAME_PROCEDURE($par1,$par2,$par3)}"){} 其中sql是数据库连接的实例 这个很好用 现在我需要参数化模式,所以我尝试以下方法: sql.call("{call ${schema}.NAME_PROCEDURE($par1,$par2,$par3)}"){} 或 但是没有成功。我不知道为什么这两段代码不起作用。仍然存在一些sqlException。我做错了什么

我正在从groovy运行一些过程:

    sql.call("{call SCHEMA.NAME_PROCEDURE($par1,$par2,$par3)}"){}
其中sql是数据库连接的实例

这个很好用

现在我需要参数化模式,所以我尝试以下方法:

    sql.call("{call ${schema}.NAME_PROCEDURE($par1,$par2,$par3)}"){}

但是没有成功。我不知道为什么这两段代码不起作用。仍然存在一些sqlException。我做错了什么

请帮忙

编辑:

我发现了类似的问题,但仍然没有答案:


我不太熟悉这一点,但我只是在挖掘我所看到的,以及其他可能发生的可能性-

  • 参数应为
    GString
    ,它与
    String
    不同。希望它能被转换,但是通过使用变量组合字符串并在稍后将其转换为GString对象[]来显式尝试

  • schema
    变量未设置正确的值

  • Sql实例可能已关闭,您可能没有正确检查该实例


  • 要比上面@mtk的答案更明确,请尝试更改:

    sql.call("{call " + schema + ".NAME_PROCEDURE($par1,$par2,$par3)}"){}
    
    致:

    您的第一次尝试将不起作用-这是尝试绑定过程的名称,它将生成以下形式的SQL:

     { call ?.NAME_PROCEDURE(?,?,?) }
    
    第二个问题稍微不那么明显。GroovySQL使用GString对象生成SQL和bindlist。但是,由于从原始字符串开始,表达式的结果将是原始字符串,因此传递给sql.call的内容将如下所示:

     { call schema.NAME_PROCEDURE(par1,par2,par2) }
    
    不是:

    这才是你真正想要的。如果par1-3都是数字,您可以接受,但如果它们是字符串(或通过替换强制为字符串的其他类型),这可能不是有效的SQL,因此您的SQL异常

    基本上是String+GString=String。Groovy SQL需要一个GString实例,以便它可以为此查询正确设置绑定列表

    您可以通过将字符串强制为“GString”实例来解决这个问题。GString定义为GString+String=GString。您可以在groovy控制台上看到这一点:

    groovy> def par1 = 1 
    groovy> def par2 = 2 
    groovy> def par3 = 3 
    groovy> def schema = 'myschema' 
    groovy> println (("{call " + schema + ".NAME_PROCEDURE($par1,$par2,$par3)}").class) 
    groovy> println ((GString.EMPTY + "{call " + schema + ".NAME_PROCEDURE($par1,$par2,$par3)}").class) 
    
    class java.lang.String
    class groovy.lang.GString$2
    

    通过将“{call”强制为GString实例,这将沿着“plus”调用级联,因此您可以确保Groovy SQL获得创建“正确”绑定列表/SQL所需的输入。

    希望这是问题的重复

    但我的答案是: 请参阅代码片段

    //getDBUSERByUserId is a stored procedure
    String getDBUSERByUserIdSql = "{call getDBUSERByUserId(?,?,?,?)}";
    callableStatement = dbConnection.prepareCall(getDBUSERByUserIdSql);
    callableStatement.setInt(1, 10);
    callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
    callableStatement.registerOutParameter(3, java.sql.Types.VARCHAR);
    callableStatement.registerOutParameter(4, java.sql.Types.DATE);
    
    // execute getDBUSERByUserId store procedure
    callableStatement.executeUpdate();
    
    String userName = callableStatement.getString(2);
    String createdBy = callableStatement.getString(3);
    Date createdDate = callableStatement.getDate(4);
    
    示例代码:

    存储过程:

    CREATE OR REPLACE PROCEDURE getDBUSERByUserId(
           p_userid IN DBUSER.USER_ID%TYPE,
           o_username OUT DBUSER.USERNAME%TYPE,
           o_createdby OUT  DBUSER.CREATED_BY%TYPE,
           o_date OUT DBUSER.CREATED_DATE%TYPE)
    IS
    BEGIN
    
      SELECT USERNAME , CREATED_BY, CREATED_DATE
      INTO o_username, o_createdby,  o_date 
      FROM  DBUSER WHERE USER_ID = p_userid;
    
    END;
    
    通过CallableStatement调用存储过程

    public class JDBCCallableStatementOUTParameterExample {
    
        private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
        private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:MKYONG";
        private static final String DB_USER = "user";
        private static final String DB_PASSWORD = "password";
    
        public static void main(String[] argv) {
            try {
                callOracleStoredProcOUTParameter();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
        private static void callOracleStoredProcOUTParameter() throws SQLException {
            Connection dbConnection = null;
            CallableStatement callableStatement = null;
            String getDBUSERByUserIdSql = "{call getDBUSERByUserId(?,?,?,?)}";
            try {
                dbConnection = getDBConnection();
                callableStatement = dbConnection.prepareCall(getDBUSERByUserIdSql);
                callableStatement.setInt(1, 10);
                callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
                callableStatement.registerOutParameter(3, java.sql.Types.VARCHAR);
                callableStatement.registerOutParameter(4, java.sql.Types.DATE);
                // execute getDBUSERByUserId store procedure
                callableStatement.executeUpdate();
                String userName = callableStatement.getString(2);
                String createdBy = callableStatement.getString(3);
                Date createdDate = callableStatement.getDate(4);
                System.out.println("UserName : " + userName);
                System.out.println("CreatedBy : " + createdBy);
                System.out.println("CreatedDate : " + createdDate);
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            } finally {
                if (callableStatement != null) {
                    callableStatement.close();
                }
                if (dbConnection != null) {
                    dbConnection.close();
                }
            }
        }
        private static Connection getDBConnection() {
            Connection dbConnection = null;
            try {
                Class.forName(DB_DRIVER);
            } catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
            }
            try {
                dbConnection = DriverManager.getConnection(
                    DB_CONNECTION, DB_USER,DB_PASSWORD);
                return dbConnection;
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
            return dbConnection;
        }
     }
    
    希望这能对你有所帮助。
    谢谢。

    这个问题需要groovy解决方案,所以香草java是不合适的。这里有一个使用“内联过程”来更好地处理参数的解决方案。grails 2.4之后还有一个sql.callWithRows和sql.callWithAllRows

        def calculateTotals(map) {
        //initialize variables
        Double returnTotalOriginalOut = 0
        Double returnTotalOtherOut = 0
        Double returnTotalNetOut = 0
    
        def sql = new Sql(sessionFactory.currentSession.connection())
        //calculate the totals
        sql.call("""
                 DECLARE
                    return_orig_chgs      number := 0;
                    return_non_orig_chgs  number := 0;
                    return_net_inst_chgs  number := 0;
                 BEGIN
                   SCHEMA.NAME_PROCEDURE(id         => ${map.id},
                                         term_in        => ${map.term},
                                         orig_chgs      => return_orig_chgs,
                                         non_orig_chgs  => return_non_orig_chgs,
                                         net_inst_chgs  => return_net_inst_chgs);
                 ${Sql.DOUBLE} := return_orig_chgs;
                 ${Sql.DOUBLE} := return_non_orig_chgs;
                 ${Sql.DOUBLE} := return_net_inst_chgs;
                END ;
        """) { return_orig_chgs, return_non_orig_chgs, return_net_inst_chgs ->
            returnTotalOriginalOut = return_orig_chgs
            returnTotalOtherOut = return_non_orig_chgs
            returnTotalNetOut = return_net_inst_chgs
        }
    
        def returnMap = [:]
        returnMap = [returnTotalOriginal: returnTotalOriginalOut, returnTotalOther: returnTotalOtherOut, returnTotalNet: returnTotalNetOut]
        return returnMap
    }
    

    如果显示实际错误,您将获得更好的反馈。“它不工作”很少有用。没有
    call()
    java.sql.Connection上的
    method
    @jtahlborn如果第一个示例有效,那么肯定有这样的方法。sql=sql.newInstance…@BillJames错误是它找不到函数。我隐约记得在Groovy中遇到过这样的错误,结果是存储过程在数据库端不存在的问题。请抓取文本实际错误,并将其放入您的问题中,以便明确哪个系统正在抱怨找不到程序。
    //getDBUSERByUserId is a stored procedure
    String getDBUSERByUserIdSql = "{call getDBUSERByUserId(?,?,?,?)}";
    callableStatement = dbConnection.prepareCall(getDBUSERByUserIdSql);
    callableStatement.setInt(1, 10);
    callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
    callableStatement.registerOutParameter(3, java.sql.Types.VARCHAR);
    callableStatement.registerOutParameter(4, java.sql.Types.DATE);
    
    // execute getDBUSERByUserId store procedure
    callableStatement.executeUpdate();
    
    String userName = callableStatement.getString(2);
    String createdBy = callableStatement.getString(3);
    Date createdDate = callableStatement.getDate(4);
    
    CREATE OR REPLACE PROCEDURE getDBUSERByUserId(
           p_userid IN DBUSER.USER_ID%TYPE,
           o_username OUT DBUSER.USERNAME%TYPE,
           o_createdby OUT  DBUSER.CREATED_BY%TYPE,
           o_date OUT DBUSER.CREATED_DATE%TYPE)
    IS
    BEGIN
    
      SELECT USERNAME , CREATED_BY, CREATED_DATE
      INTO o_username, o_createdby,  o_date 
      FROM  DBUSER WHERE USER_ID = p_userid;
    
    END;
    
    public class JDBCCallableStatementOUTParameterExample {
    
        private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
        private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:MKYONG";
        private static final String DB_USER = "user";
        private static final String DB_PASSWORD = "password";
    
        public static void main(String[] argv) {
            try {
                callOracleStoredProcOUTParameter();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
        private static void callOracleStoredProcOUTParameter() throws SQLException {
            Connection dbConnection = null;
            CallableStatement callableStatement = null;
            String getDBUSERByUserIdSql = "{call getDBUSERByUserId(?,?,?,?)}";
            try {
                dbConnection = getDBConnection();
                callableStatement = dbConnection.prepareCall(getDBUSERByUserIdSql);
                callableStatement.setInt(1, 10);
                callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
                callableStatement.registerOutParameter(3, java.sql.Types.VARCHAR);
                callableStatement.registerOutParameter(4, java.sql.Types.DATE);
                // execute getDBUSERByUserId store procedure
                callableStatement.executeUpdate();
                String userName = callableStatement.getString(2);
                String createdBy = callableStatement.getString(3);
                Date createdDate = callableStatement.getDate(4);
                System.out.println("UserName : " + userName);
                System.out.println("CreatedBy : " + createdBy);
                System.out.println("CreatedDate : " + createdDate);
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            } finally {
                if (callableStatement != null) {
                    callableStatement.close();
                }
                if (dbConnection != null) {
                    dbConnection.close();
                }
            }
        }
        private static Connection getDBConnection() {
            Connection dbConnection = null;
            try {
                Class.forName(DB_DRIVER);
            } catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
            }
            try {
                dbConnection = DriverManager.getConnection(
                    DB_CONNECTION, DB_USER,DB_PASSWORD);
                return dbConnection;
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
            return dbConnection;
        }
     }
    
        def calculateTotals(map) {
        //initialize variables
        Double returnTotalOriginalOut = 0
        Double returnTotalOtherOut = 0
        Double returnTotalNetOut = 0
    
        def sql = new Sql(sessionFactory.currentSession.connection())
        //calculate the totals
        sql.call("""
                 DECLARE
                    return_orig_chgs      number := 0;
                    return_non_orig_chgs  number := 0;
                    return_net_inst_chgs  number := 0;
                 BEGIN
                   SCHEMA.NAME_PROCEDURE(id         => ${map.id},
                                         term_in        => ${map.term},
                                         orig_chgs      => return_orig_chgs,
                                         non_orig_chgs  => return_non_orig_chgs,
                                         net_inst_chgs  => return_net_inst_chgs);
                 ${Sql.DOUBLE} := return_orig_chgs;
                 ${Sql.DOUBLE} := return_non_orig_chgs;
                 ${Sql.DOUBLE} := return_net_inst_chgs;
                END ;
        """) { return_orig_chgs, return_non_orig_chgs, return_net_inst_chgs ->
            returnTotalOriginalOut = return_orig_chgs
            returnTotalOtherOut = return_non_orig_chgs
            returnTotalNetOut = return_net_inst_chgs
        }
    
        def returnMap = [:]
        returnMap = [returnTotalOriginal: returnTotalOriginalOut, returnTotalOther: returnTotalOtherOut, returnTotalNet: returnTotalNetOut]
        return returnMap
    }