Q: I'm using your JDBCR4 tool to access a database on another server. It works well as long as I want my data returned as single-byte EBCDIC text, but if there are any double-byte characters, I have problems. How can I handle double-byte data in JDBCR4?
A: This article provides additional routines for JDBCR4, and these routines provide Unicode support.
Over the last two years, I've published a series of articles that discuss how to access data on an external database server (e.g., MySQL, Microsoft SQL Server, Oracle) from an RPG program. By interfacing RPG with Java, I can use Java's JDBC drivers to connect to almost any type of database. I've provided an RPG service program called JDBCR4 that you call from your ILE RPG programs to access these external databases. In this article, I add Unicode support to JDBCR4, and I also provide links to previous articles about using JDBC from RPG.
RPG has its own built-in support for UCS-2 Unicode. Instead of declaring your variable as A=Alphanumeric, you declare it as C=UCS-2 Character, and then you use it exactly the same way you'd use any other character string. The %char() function will convert a UCS-2 field to an alphanumeric (EBCDIC) field, and the %ucs2() function will convert the other direction, from EBCDIC to UCS-2 Unicode.
For example, if I wanted to declare an RPG field that's 100 characters long, I can declare it as 100C if it want Unicode, or 100A if I want regular EBCDIC data.
D myUnicode s 100C
D myEbcdic s 100a
/free
myUnicode = %ucs2('Hello World');
myEBCDIC = %char(myUnicode);
The advantage of the Unicode field is that it supports all the characters supported by Unicode, which means almost every character used in every language. The same Unicode variable can store both English text and Korean text without doing anything fancy, because Unicode supports all the characters from both languages.
Java uses Unicode for everything internally, so it was very easy to ask RPG to pass Unicode data to Java instead of EBCDIC data. The only tricky part is that my routines need to know whether you're passing EBCDIC to them or whether you're passing Unicode to them, so I needed to use separate subprocedures for Unicode vs. EBCDIC. Here are the new subprocedures I added to JDBCR4:
| New Unicode Routine | Existing EBCDIC Routine | Description |
|---|---|---|
| JDBC_getColC | JDBC_getCol | Retrieve column value for a column identified by ordinal column number. |
| JDBC_getColByNameC | JDBC_getColByName | Retrieve column value for a column identified by column name. |
| JDBC_setStringC | JDBC_setString | Set the value of a parameter marker (for a column) from a character string. |
| JDBC_prepStmtC | JDBC_prepStmt | Prepare an SQL statement from a character string. |
| JDBC_callStmtC | JDBC_callStmt | Prepare an SQL statement that calls a stored procedure from a character string. |
With these new routines, working with the data as Unicode is just as easy as working with the data in EBCDIC. Just declare your variables as Unicode and call the Unicode procedure instead of the EBCDIC one. No other changes needed!
You can download the new JDBCR4 with Unicode support from the following link:
http://systeminetwork.com/files/RpgAndJdbc.zip
Here are links to the previous articles I've written about using JDBC from RPG. NOTE: The code from this article (above) contains all sample programs from the following articles, but also contains bug fixes. Please use this article's code.
hi Paul,
All I can tell from your call stack is that it's having trouble starting the Java Virtual Machine (JVM) -- and the reason I know that is because it's in the START_JVM procedure that it's having trouble. To explore your question further, I'd need to see a detailed job log, since at this point, I don't even know what the exception is.
Thanks for the code. I have only slightly modded the MSSQLTEST pgm for the log in credetials connection string but I am getting an MCH3601 - The call to JDBC_PROPE ended in error. It's on the prop = JDBC_Properties(); after it's set the CLASSPATH. The call stack is:
QCMD QSYS /04F3 1 MUX010 M4AMSYS 56200 /033B MUX030 M4AMSYS 344200 /19D1 2 MUX070 M4AMSYS 10900 /0075 QCMDEXC QSYS /012F GROVERP QGPL 1500 /0028 3 QCMD QSYS /01C7 MSSQLTEST JVALIB _QRNP_PEP_MSSQLTEST MSSQLTEST JVALIB 6700 MSSQLTEST JDBCR4 JVALIB 4090 JDBC_PROPERTIES JDBCR4 JVALIB 5667 JDBC_GET_JNI_ENV JDBCR4 JVALIB 5840 START_JVM QRNXUTIL QSYS 132 _QRNX_JNI_ONE_CALL QRNXUTIL QSYS 18 _QRNX_JNI_CHK_EXCP QRNXIE QSYS 1 _QRNX_CALL_FC_H QRNXIE QSYS 2 _QRNX_DFT_ERROR QRNXIE QSYS 17 _QRNX_INQ QRNXIE QSYS 4 InqMsg QMHSNDPM QSYS /0A80 QMHSNINQ QSYS /0102 QMHDSEXT QSYS /00FB QDMACCIN QSYS /015CThe weird thing being is that I ran it yesterday and it worked fine. Is there anything obvious that I'm doing wrong ? Any ideas would be a real help. Thanks.