× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



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.
> 
> Elvis
> 
> -----Original Message-----
>  Subject: [C400-L] SQLC and null-terminated strings
> 
>    Newbie C question:  What is the expected behavior
> (using SQL embedded in a C program) of an insert
> when
> the host variable is a null-terminated string? 
> Regardless of the size of the host variable, the
> value
> of the CNULRQD option (or the selection of
> *CNULRQD/*NOCNULRQD on the compile), the type of the
> table field (char or graphic), or the phase of the
> moon -- or several other things I tried -- my result
> is always blank-padded.  I am on a V5R1 machine (not
> current on ptf's), but replicated this on a V5R3
> machine.
>    What I find odd is that I prototyped this in
> RPGLE
> (with embedded SQL) and this does write nulls.
> 
> Thanks,
> Don Whittaker
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

As an Amazon Associate we earn from qualifying purchases.

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-2024 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 on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.