Java 如何从groovy调用参数化sql过程
我正在从groovy运行一些过程: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。我做错了什么
sql.call("{call SCHEMA.NAME_PROCEDURE($par1,$par2,$par3)}"){}
其中sql是数据库连接的实例
这个很好用
现在我需要参数化模式,所以我尝试以下方法:
sql.call("{call ${schema}.NAME_PROCEDURE($par1,$par2,$par3)}"){}
或
但是没有成功。我不知道为什么这两段代码不起作用。仍然存在一些sqlException。我做错了什么
请帮忙
编辑:
我发现了类似的问题,但仍然没有答案:
我不太熟悉这一点,但我只是在挖掘我所看到的,以及其他可能发生的可能性-
GString
,它与String
不同。希望它能被转换,但是通过使用变量组合字符串并在稍后将其转换为GString对象[]来显式尝试
schema
变量未设置正确的值要比上面@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
}