これに対処する最善の方法は、ホスト変数を使用することです。つまり、値を引用符で囲む必要はありません。Informixは、文字列を他のタイプに変換するのに非常に優れています。問題が発生する唯一のタイプは、BLOB(BYTE、TEXT、BLOB、CLOB)です。
このコードはコンパイルされただけです。実行されていません。さまざまなreturn
ステートメントは、最後を除いてエラーリターンです。プリペアドステートメントを解放せずに戻ることが正しいかどうかを議論することができます。そうではないことは容易に議論の余地があります。このモンスターから構築されたいくつかのルーチンがあるはずです。
#include "sqlca.h"
#include "sqlda.h"
#include "sqltypes.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
extern int insert_record(char *line, const char *tabname);
int insert_record(char *line, const char *tabname)
{
/* Analyze line */
char *pipe = strchr(line, '|');
char *comma = line;
int c_count = 0;
int v_count = 0;
while ((comma = strchr(comma, ',')) != 0 && comma < pipe)
c_count++;
comma = pipe;
while ((comma = strchr(comma, ',')) != 0)
v_count++;
if (v_count != c_count)
return(-1);
char *names[c_count];
char *value[c_count];
char *np = line;
char *vp = pipe+1;
for (int i = 0; i < c_count; i++)
{
names[i] = np;
value[i] = vp;
char *sep = strchr(np, ',');
assert(sep != 0);
if (sep > pipe)
sep = pipe;
*sep = '\0';
np = sep + 1;
sep = strchr(vp, ',');
if (sep != 0)
{
*sep = '\0';
vp = sep + 1;
}
}
/* Create SQL statement with placeholders */
/* names[i] contains column name for entry i; value[i] contains the value */
$ char buffer[4096];
char *sql = buffer;
int len = sizeof(buffer) - 1;
int num = snprintf(sql, len, "insert into %s", tabname);
if (num <= 0 || num >= len)
return(-2);
if (num <= 0 || num >= len)
return(-2);
sql += num;
len -= num;
pad = "(";
for (int i = 0; i < c_count; i++)
{
num = snprintf(sql, len, "%s%s", pad, "?");
if (num <= 0 || num >= len)
return(-2);
sql += num;
len -= num;
}
num = snprintf(sql, len, ")");
if (num <= 0 || num >= len)
return(-2);
$ PREPARE p_insert FROM :buffer;
if (sqlca.sqlcode != 0)
return(sqlca.sqlcode);
/* Create sqlda to describe strings */
ifx_sqlda_t data;
ifx_sqlvar_t columns[c_count];
$ struct sqlda *udesc = &data;
data.sqld = c_count;
data.sqlvar = columns;
data.desc_name[0] = '\0';
data.desc_occ = 0;
data.reserved = 0;
data.desc_next = 0;
for (int i = 0; i < c_count; i++)
{
columns[i].sqltype = SQLVCHAR;
columns[i].sqllen = strlen(value[i]);
columns[i].sqldata = value[i];
columns[i].sqlind = 0;
columns[i].sqlname = names[i];
columns[i].sqlformat = 0;
columns[i].sqlitype = 0;
columns[i].sqlilen = 0;
columns[i].sqlidata = 0;
columns[i].sqlxid = 0;
columns[i].sqltypename = 0;
columns[i].sqltypelen = 0;
columns[i].sqlownerlen = 0;
columns[i].sqlsourcetype = 0;
columns[i].sqlownername = 0;
columns[i].sqlsourceid = 0;
columns[i].sqlilongdata = 0;
columns[i].sqlflags = 0;
columns[i].sqlreserved = 0;
}
/* Execute the SQL and clean up */
$ EXECUTE p_insert USING DESCRIPTOR udesc;
if (sqlca.sqlcode != 0)
return(sqlca.sqlcode);
$ FREE p_insert;
if (sqlca.sqlcode != 0)
return(sqlca.sqlcode);
return(0);
}