Elvis,
   Thanks for the info.  And sorry for the sloppy
code; I was trying to condense the orginal into the
least amount of lines for testing.
   So the answer to my orginal question would be "The
expected behavior is for the insert to drop the null
character(s) and pad with blank(s), and that is done
by SQL (and so the *CNULRQD is not pertinent)."
   So I guess my step is to post to the RPG list to
see why embedded SQL in RPGLE _is_ writing the null
character(s)....

Thanks,
Don Whittaker
   

--- Elvis Budimlic
<ebudimlic@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:

> Your base issue is that SQL performs data validation
> when it writes
> (inserts) records, instead of traditional RPG way of
> doing data validation
> on the reads.
> If you run your program under debug (just type
> STRDBG in your interactive
> session) you'll see that one of the messages is
> SQL7939.  Here is the
> relevant text from that message:
> 
>
===================================================================
> Message . . . . :   Data conversion required on
> INSERT or UPDATE.
> Cause . . . . . :   The INSERT or UPDATE values can
> not be directly moved to
> 
>   the columns because the data type or length of a
> value is different than
> one
>   of the columns. The INSERT or UPDATE statement ran
> correctly.
> Performance, 
>   however, would be improved if no data conversion
> was required. The reason
> 
>   data conversion is required is 3.
> 
> ......
>    -- Reason 3 is that the INSERT or UPDATE value is
> a variable length
> string
>  and column FLD2 is not.
> 
> ......
> Recovery  . . . :   To get better performance, try
> to use values of the same
> 
>   type and length as their corresponding columns.
> 
>
===================================================================
> 
> So, everything is working as designed (WAD as IBM
> puts it).
> Even if you find a way to turn off data validation,
> I would strongly
> recommend against it as it safeguards you from
> future errors.  
> If you really need to place invalid data into the
> character field, you'll
> need to use native I/O.  RPG is an obvious
> candidate, but you can do it in C
> using _R* functions (i.e. _Ropen, _Rwrite, _Rclose).
>  No data validation
> takes place on writes and very little on reads.
> 
> I have some general questions on your test code
> unrelated to the error you
> are seeing.  
> 
> *  memset(wrkFld2, 0, 64); 
> It is bad practice to hardcode array size like this.
>  Use this instead:
>    memset(wrkFld2, 0, sizeof(wrkFld2);
> 
> *  memcpy(wrkFld2, "From C", sizeof(wrkFld2));
> Your input buffer "From C" has size of 7 bytes, and
> you are copying 64 bytes
> starting at the undefined address of the temporary
> buffer "From C".  Most of
> the time you'll get lucky and what follows those 7
> bytes will be hex zeros
> (nulls), but there is no guarantee.  Here is one
> possible correction, but I
> list another in the alternate source on the bottom:
>    memcpy(wrkFld2, "From C", strlen("From C") >
> sizeof(wrkFld2) ?
> sizeof(wrkFld2) : strlen("From C");
> 
> * tPtr = (char *)&wrkFld2;
> You are pointing tPtr to the address of wrkFld2
> pointer, which is not what
> you intended to do.  You intended to point it to the
> address of what wrkFld2
> pointer is pointing to.  Yes, I said wrkFld2 is a
> pointer! It points to the
> address allocated by those 64 bytes.  This is what
> you should have used:
> tPtr = wrkFld2 + 7;
> Why it worked in your test program?  Because
> compiler took care of you.  But
> not all compilers will do that.
> 
> Here is my take on your test code just for
> illustration purposes (i.e. it
> fails with the same data conversion error):
> 
> #include <stdlib.h>                                 
>                        
> #include <string.h>                                 
>                        
>                                                     
>                        
> EXEC SQL INCLUDE SQLCA;                             
>                        
>                                                     
>                        
> int main(int args, char *argv[] )  {                
>                        
>     EXEC SQL BEGIN DECLARE SECTION;                 
>                        
>        long     wrkFld1;                            
>                        
>        char     wrkFld2[64];                        
>                        
>     EXEC SQL END DECLARE SECTION;                   
>                        
>     char testStr[] = "From C";                      
>                        
>     int len = strlen(testStr);                      
>                        
>                                                     
>                        
>     memset(wrkFld2, 0, sizeof(wrkFld2));            
>                        
>     wrkFld1 = 11;                                   
>                        
>     memcpy(wrkFld2, testStr, len > sizeof(wrkFld2) ?
> sizeof(wrkFld2) : len);
>                                                     
>                        
>     EXEC SQL                                        
>                        
>        insert into QGPL/TESTSQL3                    
>                        
>              ( Fld1, Fld2)          
>       values ( :wrkFld1, :wrkFld2); 
> }                                   
>   
> I realize I probably over-explained this, but I
> always wished someone
> explained these things to me when I was getting
> started with C programming
> on the iSeries.
> 
> Good luck with your project and post back if you
> have other issues.
> 
> Elvis
> 
> -----Original Message-----
> From:
>
c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx
>
[mailto:c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx]
> On
> Behalf Of Donald Whittaker
> Sent: Tuesday, September 20, 2005 1:10 PM
> To: C programming iSeries / AS400
> Subject: RE: [C400-L] SQLC and null-terminated
> strings
> 
> Fat fingered the earlier reply - sorry.
> 
> CREATE TABLE QGPL/TESTSQL2 
>    (FLD1 INT NOT NULL WITH DEFAULT, 
>     FLD2 CHAR (64) NOT NULL WITH DEFAULT)           
>  
>                  
> 
> #include <stdlib.h>
> #include <string.h>
>  main(int args, char *argv[] )  {  
>     char              *tPtr = NULL;
>     EXEC SQL INCLUDE SQLCA;          
>                                      
>     EXEC SQL BEGIN DECLARE SECTION;  
>        long     wrkFld1;               
>        char     wrkFld2[64];           
>     EXEC SQL END DECLARE SECTION;    
>                                                 
>     memset(wrkFld2, 0, 64);                     
>     wrkFld1 = 11;                               
>     memcpy(wrkFld2, "From C", sizeof(wrkFld2)); 
>     tPtr = (char *)&wrkFld2;          
>     tPtr = tPtr + 7;                 
>     memset( tPtr, 0, 57);             
>                                       
>     EXEC SQL                          
>        insert into QGPL/TESTSQL2      
>               ( Fld1, Fld2)           
>        values ( :wrkFld1, :wrkFld2);  
>  }  /* END  main()   */   
> 
> 
> --- Elvis Budimlic
> <ebudimlic@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> 
> > Show some code please.  
> > And your CREATE TABLE statement so we can see your
> > field definitions.
> > 
> 
=== message truncated ===



                
__________________________________ 
Yahoo! Mail - PC Magazine Editors' Choice 2005 
http://mail.yahoo.com

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available here. If you have questions about this, please contact [javascript protected email address].