|
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 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.