我试图了解如何使用CLOB
将JDBC
传递给数据库。我使用的是Oracle 11g
和Oracle's JDBC Driver 12.1.0.1
。
我正在浏览Oracle的Jdbc教程和I found this sample code。它读取文件的内容并写入Clob实例,然后使用INSERT
将其写入数据库。为了便于阅读,我只发布代码的相关部分:
Clob myClob = this.con.createClob();
Writer clobWriter = myClob.setCharacterStream(1);
String str = this.readFile(fileName, clobWriter);
System.out.println("Wrote the following: " +
clobWriter.toString());
if (this.settings.dbms.equals("mysql"))
{
System.out.println("MySQL, setting String in Clob " + "object with setString method");
myClob.setString(1, str);
}
System.out.println("Length of Clob: " + myClob.length());
String sql = "INSERT INTO COFFEE_DESCRIPTIONS " + "VALUES(?,?)";
pstmt = this.con.prepareStatement(sql);
pstmt.setString(1, coffeeName);
pstmt.setClob(2, myClob);
pstmt.executeUpdate();
以下是readFile
方法的代码:
private String readFile(String fileName, Writer writerArg) throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String nextLine = "";
StringBuffer sb = new StringBuffer();
while ((nextLine = br.readLine()) != null)
{
System.out.println("Writing: " + nextLine);
writerArg.write(nextLine);
sb.append(nextLine);
}
// Convert the content into to a string
String clobData = sb.toString();
// Return the data.
return clobData;
}
我修改了上面的示例代码,以便将CLOB传递给PL / SQL过程。
public String handleEmployeeReview(int empId , String fileName) throws IOException
{
Connection conn = null;
CallableStatement callStmt = null;
String reviewContent = null;
try
{
// Register the Oracle Jdbc driver
// Class.forName(JDBC_DRIVER_ORACLE);
// Create a database connection
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);
// Create a query string
String callProc = " { call HR.EMP_PKG.handle_employee_review ( ? , ? , ? ) } ";
// Create a Callable Statement
callStmt = conn.prepareCall(callProc);
// Bind values to the first IN parameter
callStmt.setInt(1, empId);
// Create CLOB and use ClobWriter
Clob reviewFileClob = conn.createClob();
Writer clobWriter = reviewFileClob.setCharacterStream(1);
String reviewStr = this.readFile(fileName , clobWriter);
callStmt.setClob(2, reviewFileClob);
// Register OUT parameter
callStmt.registerOutParameter(3, java.sql.Types.VARCHAR);
// Execute the callable statement
callStmt.execute();
// Retreive the OUT parameters
reviewContent = callStmt.getString(3);
System.out.println("Employee with id : "+ empId + " has annual review : " + reviewContent);
}
这是PL / SQL程序:
-- PURPOSE: Takes Clob and returns its contents
-- Example of: PROCEDURE that takes a Clob as IN parameter
PROCEDURE handle_employee_review(empId IN VARCHAR2 , empReviewDoc IN CLOB , reviewContent OUT VARCHAR2) IS
BEGIN
reviewContent := empReviewDoc || ' THIS IS COMING FROM THE DATABASE';
EXCEPTION
WHEN others THEN
dbms_output.put_line('Error!');
END handle_employee_review;
在运行我修改后的代码时,我看不到任何被发送到数据库的内容。我如何让这段代码工作?似乎writerArg.write(nextLine);
方法中的这一行readFile
未按预期工作?以下是我的代码的输出:
Employee with id : 101 has annual review : THIS IS COMING FROM THE DATABASE
这是我的调试器的快照。我确实看到数据被写入CLOB的作家
如果您注意到上述o / p,PL / SQL代码在CLOB中找不到任何内容。
另一方面,如果我按照以下方式将内容传递给CLOB(教程的示例也使用但仅用于MYSQL数据库)。 我还使用setString
方法将文件内容传递给CLOB,而不使用Clob的Writer实例。它运作得很好。
Clob reviewFileClob = conn.createClob();
String reviewStr = this.readFile(fileName , clobWriter);
reviewFileClob.setString(1, reviewStr);
callStmt.setClob(2, reviewFileClob);
这给了我以下输出:
Employee with id : 101 has annual review : Employee Exceeds Expectations THIS IS COMING FROM THE DATABASE
注意:我已经删除了原始代码(删除了try catch blocks,数据库/文件资源清理)以仅发布相关代码。这篇文章有点过于冗长。