Expose %Stream property in JDBC as CLOB
I need to reproduce a table (in fact a view, but let's start with a simple table 😊) in IRIS as the currently used in Oracle.
I need to expose/project one column to JDBC as CLOB, in my class I have the corresponding property defined as:
Property GlobStream As %Stream.GlobalCharacter;
In JDBC this column is projected as LONGVARCHAR, this is compliant with the documentation but I need to project it as CLOB.
In addition, I'm no expert in JDBC but wit seems that LONGVARCHAR has a Maximum Length 32,700 characters in JDBC, not quite enough for an arbitrary stream.
Is it possible to project a %Stream to JDBC as a CLOB?
If so, how?
If not, why? How can I give access to IRIS stream properties via JDBC?
Comments
%Stream.GlobalCharacter properties in InterSystems IRIS are projected as LONGVARCHAR (-1) for JDBC. This complies with the default mapping, and the JDBC specification applies the maximum length limit for LONGVARCHAR, which may not suit arbitrary stream data requirements.
To utilize CLOBs adequately, the JDBC standard interfaces provide BLOB and CLOB handling. For instance, you can retrieve and set CLOB data within a Java program utilizing the java.sql.Clob interface:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT MyCLOBColumn FROM MyTable");
rs.next(); // Access the Clob data
java.sql.Clob clob = rs.getClob(1);
// Example to print length
System.out.println("Clob length = " + clob.length());
// Perform further operations
clob.free(); // Close explicitly
This demonstrates the correct interaction between Java and CLOB stream data types in IRIS. Ensure that your implementation explicitly opens and manages stream field attributes to prevent constraints like JDBC defaults on LONGVARCHAR types from becoming limiting. [1]
Sources:
@DC AI Bot 😁thank you for the sample code on how to consume a CLOB via JDBC, unfortunately I need to expose a CLOB to JDBC! 😞
See
- Using Stream Fields from ODBC
- Integer Codes for Data Types
- LONGVARCHAR = CLOB = %Stream.GlobalCharacter
If you run the following code, then the type of variables a and b in the generated class will be %Stream.GlobalCharacter
create table dc.test ( a LONGVARCHAR, b CLOB )
In addition, I'm no expert in JDBC but wit seems that LONGVARCHAR has a Maximum Length 32,700 characters in JDBC, not quite enough for an arbitrary stream.Max Size for LONGVAR(BINARY/CHAR) = 2147483647, for VAR(BINARY/CHAR) = 4096
PS: By the way, in DbVisualizer you can view all types supported by the InterSystems IRIS JDBC driver, their numeric codes, maximum sizes, and much more.
Hi @Vitaliy Serdtsev thank you for your answer, however I need to reproduce the same interface/definition as currently implemented in Oracle that is using a CLOB column.
The JDBC client access the Oracle table and is implemented (for that column) using a CLOB that (I believe) it's different than accessing a LONGVARCHAR. The idea would be to use IRIS instead of Oracle without changing (most of) the code.
Where is defined/documented the JDBC LONGVARCHAR maximum length?
My search cannot find any reference on max size of 2147483647
jdbc Clobs map to LONGVARCHAR which have no limit in size.
The 2147483647 number is the max size for an integer and is an artificial max value from Oracle, but likely they can hold much more when stored in the database.
I would like to clarify once again that the InterSystems JDBC driver itself returns its current limits on the maximum size of certain types of data that can be viewed by any JDBC client (DbVisualizer, SQuirreL, etc.).
Let's check together in practice the maximum size of LONGVARCHAR in the InterSystems JDBC driver.
Class dc.test Extends %Persistent
{
Property Note As %Stream.GlobalCharacter;
}import java.io.*;
import java.sql.*;
class IRISDemo
{
public static void main(String[] args)
{
Connection db = null;
try
{
File file = new File("C:\\big.iso");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
Class.forName("com.intersystems.jdbc.IRISDriver");
DriverManager.setLoginTimeout(3);
db = DriverManager.getConnection("jdbc:IRIS://localhost:1972/USER", "_SYSTEM", "SYS");
PreparedStatement ps = db.prepareStatement("update dc.test set Note=? where id=1");
ps.setCharacterStream(1, br, file.length());
System.out.printf("Result = %s", ps.executeUpdate()).println();
ps.close();
db.close();
System.out.println("OK!");
} catch (Exception e)
{
e.printStackTrace();
}
}
}If the file size exceeds 2147483647 characters, the following error occurs:
java.sql.SQLException: Stream too long: 2895740928 at com.intersystems.jdbc.IRISPreparedStatement.setCharacterStream(IRISPreparedStatement.java:889)
Where is defined/documented the JDBC LONGVARCHAR maximum length? My search cannot find any reference on max size of 2147483647
LONG VARCHARORACLE The LONG VARCHAR data type stores data from and into an Oracle AI Database LONG column. The first 4 bytes of a LONG VARCHAR contain the length of the item. So, the maximum length of a stored item is 2^31-5 bytes.
BLOBs and CLOBsIRIS BLOBs and CLOBs can store up to 4 Gigabytes of data (the limit imposed by the JDBC and ODBC specifications). The default data types that store BLOBs and CLOBs in InterSystems SQL are automatically compressed.
Although the documentation differs from what the IRIS JDBC driver returns, in this case I tend to believe the driver more than the documentation ;)
In addition, in the %AbstractStream class, the MAXLEN parameter is 2147483647.
I need to reproduce the same interface/definition as currently implemented in Oracle that is using a CLOB column.
In IRIS JDBC, the CLOB type is not provided by design: OdbcType (Class Keyword)
But this is not a problem, as the Oracle and IRIS drivers support transparent transformations for streaming data types:
Thank you @Jim Nelson and @Vitaliy Serdtsev