|
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
As an Amazon Associate we earn from qualifying purchases.
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.