Re: Load Table in ESQL/C
Posted in 1993
>} >} Hi Netlanders, >} >} I've got following problem: >} With ISQL I can easily load a table with >} >} LOAD FROM "file_name" INSERT INTO table_name >} >} Now I want ESQL/C to do the same job and here is the problem. > For my applications I end up building a .sql > load file and calling it from the ESQL/C program. > For your situation not having sql installed - I say good luck!! It's not *that* tough to write in C! OK, it *would* take some time to write a real program that parses the "load from" syntax, and looks up the table and figures out the column types and all that, but if you just need to do it for one or two tables you can write a throw-away C program. Following are some useful code fragments for reading in strings in unload format. There's one caveat in this: My functions recognize the convention of "\\" escaping a control character. Thus, if a field contains a newline, my functions will correctly interpret that newline as part of the field as long as it's prefixed with the \\. My memory is a bit fuzzy, but I *think* that my version of isql was pretty brain-damaged about handling control characters in unload files. On output, it would output them literally (without the \\), and on import, it would (of course) bomb. I don't know whether or not Informix has gotten more reasonable about unload files. So, if your unload file contains "a|b\\|c|d\\\\|", my code will interpret it as three fields, one containing "a", the next containing "b|c", and the third containing "d\\". I seem to remember Informix's load/unload bombing on this kind of data, but that *was* a few years ago. Anyway, here are the routines. I included "get_load_address()" as an example of the thing being used for a specific table. It shouldn't take much to change this to whatever table layout, do any data conversions, and add an insert. Enjoy! Bill int get_u_string(FILE *fp, char *s, int l) /* This routine will get a string from file fp and put it in s. The maximum length of s is l. It will return TRUE if successful, or FALSE if EOLN is seen. The internal flag truncated isn't used, but it could be to issue an error message, if this is desirable. */ { int c; int i; int end_seen; int truncated; truncated=FALSE; i=0; while ((c = getc(fp)) != EOF && c != ((int) '\\n') && c != ((int) '|')) { if (i < l) { i++; if (c == '\\\\') { c=getc(fp); if (c != '\\\\' && c != '|' && !iscntrl(c)) { ungetc(c, fp); c = '\\\\'; } } if (c != EOF) (*(s++)) = ((char)c); } else truncated=TRUE; } end_seen = (c == EOF || c == '\\n'); while (i < l) { (*(s++)) = ' '; i++; } (*s) = '\\0'; return !end_seen; } int get_u_eoln(FILE *fp) /* This routine will move fp to after the next end of line. */ { int c; char do_it[2]; int spurious; static int skip=TRUE; /* Flag that we want to allow spurious characters at the end of a line */ spurious = FALSE; while ((c=getc(fp)) != EOF && c != '\\n') spurious=TRUE; if (skip || !spurious) return TRUE; assert(FALSE); } boolean get_load_address(fp) /* Get an address from fp in unload format. Return TRUE if there's an address, FALSE otherwise. */ FILE *fp; { if (!get_u_string(fp, a_sequence, 10)) return FALSE; if ( get_u_string(fp, a_first_name, 14) && get_u_string(fp, a_last_name, 30) && get_u_string(fp, a_company, 30) && get_u_string(fp, a_address1, 30) && get_u_string(fp, a_address2, 30) && get_u_string(fp, a_city, 20) && get_u_string(fp, a_state, 2) && get_u_string(fp, a_zip, 30) && get_u_string(fp, a_phone_no, 30) && get_u_string(fp, a_title, 30) && get_u_string(fp, a_comment1, 40) && get_u_string(fp, a_status, 1) && get_u_eoln(fp)) { return TRUE; } else { fprintf(stderr, "Error in unload-format input\\n"); assert(FALSE); } } -- Bill Foote bill@pds.com PDS Corp, Los Angeles, CA USA uunet!promdist!bill