As400 ISeries 数据库中的非常大的字段

very large fields in As400 ISeries database

我想将一个大 XML 字符串(可能长于 32K 或 64K)保存到 AS400 文件字段中。 DDS 或 SQL 文件都可以。下面的 SQL 文件示例。

CREATE TABLE MYLIB/PRODUCT
(PRODCODE DEC (5 ) NOT NULL WITH DEFAULT,
PRODDESC CHAR (30 ) NOT NULL WITH DEFAULT,
LONGDESC CLOB (70K ) ALLOCATE(1000) NOT NULL WITH DEFAULT)

我们将使用 RPGLE 来读取和写入字段。

目标是在客户端通过 ODBC 连接提取数据。

AS400 字符字段似乎有 32K 的限制,所以这不是一个很好的选择。

我有什么选择?我一直在阅读 CLOB,但似乎有限制将大字符串写入 CLOBS 和远程读取 CLOB 字段。请注意,客户端(仍然)在 AS400 OS.

的 v5R4 上

谢谢!


Charles 在下面的回答显示了如何提取数据。我想插入数据。此代码运行,但抛出“22501”SQL 错误。

D wLongDesc       s          65531a   varying                      
D longdesc        s                   sqltype(CLOB:65531)          

 /free                                                             
    //eval longdesc = *ALL'123';                                   
    eval Wlongdesc = '123';                                        

    exec SQL                                                       
    INSERT INTO PRODUCT (PRODCODE, PRODDESC, LONGDESC)             
    VALUES (123, 'Product Description', :LongDesc );               

    if %subst(sqlstt:1:2) <> '00';                                 
       // an error occurred.                                       
    endif;                                                         

    // get length explicitly, variables are setup by pre-processor 
    longdesc_len = %len(%trim(longdesc_data));                     

    wLongDesc = %subst(longdesc_data:1:longdesc_len);              

 /end-free                                                         
C                   Eval      *INLR = *on                          
C                   Return                                         

附加问题:这种技术是否适用于存储我想稍后通过 ODBC 连接提取的数据? ODBC 将 CLOB 读取为指针还是可以提取文本?

在v5r4,RPGLE实际上支持64K字符变量。

但是,对于常规 char/varchar 字段,数据库限制为 32K。

对于大于 32K 的任何内容,您都需要使用 CLOB。

如果你能忍受 64K(左右)

CREATE TABLE MYLIB/PRODUCT
(PRODCODE DEC (5 ) NOT NULL WITH DEFAULT,
PRODDESC CHAR (30 ) NOT NULL WITH DEFAULT,
LONGDESC CLOB (65531) ALLOCATE(1000) NOT NULL WITH DEFAULT)

可以使用RPGLESQLTYPE支持

 D code            S              5s 0
 d wLongDesc       s          65531a   varying
 D longdesc        s                   sqltype(CLOB:65531)

  /free
   exec SQL
     select  prodcode, longdesc
      into :code, :longdesc
      from mylib/product
     where prodcode = :mykey;

   wLongDesc = %substr(longdesc_data:1:longdesc_len);
   DoSomthing(wLongDesc);

预编译器将用如下定义的 DS 替换 longdesc:

 D longdesc        ds
 D  longdesc_len                 10u 0
 D  longdesc_data             65531a

您可以直接使用它,确保最多只使用 longdesc_len 或像我上面那样将其转换为 VARYING。

如果绝对必须处理大于 64K 的...

  1. 升级到 OS 的受支持版本(支持 16MB 变量)
  2. 使用文件引用通过 IFS 文件访问 CLOB 内容

选项 2 是我从未见过的选项....而且我找不到任何示例。刚刚看到这篇旧文章中提到的.. http://www.ibmsystemsmag.com/ibmi/developer/general/BLOBs,-CLOBs-and-RPG/?page=2

此示例展示了如何在 Charles 和 Murphy 的反馈帮助下写入 Db2 数据库中的 CLOB 字段。

 * ----------------------------------------------------------------------         
 * Create table with CLOB:
 *   CREATE TABLE MYLIB/PRODUCT 
 *   (MYDEC  DEC (5 ) NOT NULL WITH DEFAULT,                                        
 *   MYCHAR CHAR (30 ) NOT NULL WITH DEFAULT,                                       
 *   MYCLOB CLOB (65531) ALLOCATE(1000) NOT NULL WITH DEFAULT)                      
 * ----------------------------------------------------------------------         

D PRODCODE        S              5i 0                                             
D PRODDESC        S             30a                                               

D i               S             10i 0                                             
D wLongDesc       s          65531a   varying                                     
D longdesc        s                   sqltype(CLOB:65531)                         

D* Note that variables longdesc_data and longdesc_len                             
D* get create automatocally by SQL pre-processor.                                 

 /free                                                                   
   eval wLongdesc = '123';                                              

   longdesc_data = wLongDesc;                                           
   longdesc_len = %len(%trim(wLongDesc));                               

   exec SQL set option commit = *none;                                  

   exec SQL                                                             
    INSERT INTO PRODUCT (MYDEC, MYCHAR, MYCLOB)                         
   VALUES (123, 'Product Description',:longDesc);                       

   if %subst(sqlstt:1:2)<>'00' ;          
      // an error occurred.               
   endif;                                 

   Eval *INLR = *on;                      
   Return;                                
 /end-free