在我的C程序中,我收到的输入格式为
"name,age,salary|Richard,35,10000"
现在我想从此输入框架插入和更新查询。
我正在使用strtok_r
和strtok
来实现此目的。
但我的问题是,在插入或更新时,我必须在varchar数据类型周围使用双引号,如“Richard”。
输入没有固定的模式,它可以是任何顺序。
我是否每次都要检查每列的数据类型?
有更好的方法吗?
我使用的数据库是Informix。我使用的是ESQL / C,它是带有嵌入式SQL扩展的旧C。
答案 0 :(得分:1)
处理此问题的最佳方法是通过主机变量,这意味着您不需要围绕值进行引用。 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);
}