C 从输入中查询表单数据库

C 从输入中查询表单数据库,c,database,informix,C,Database,Informix,在我的C程序中,我接收的输入是 "name,age,salary|Richard,35,10000" 现在,我想从这个输入框插入和更新查询 为此,我正在使用strtok\u r和strtok 但我的问题是,在插入或更新时,必须在varchar数据类型(如“Richard”)周围使用双引号 输入没有固定的模式,可以是任何顺序 我是否每次都必须检查每一列的数据类型 有更好的方法吗 我使用的数据库是Informix。我使用的是ESQL/C,它是带有嵌入式SQL扩展的旧C。处理这个问题的

在我的C程序中,我接收的输入是

     "name,age,salary|Richard,35,10000"
现在,我想从这个输入框插入和更新查询

为此,我正在使用
strtok\u r
strtok

但我的问题是,在插入或更新时,必须在varchar数据类型(如“Richard”)周围使用双引号

输入没有固定的模式,可以是任何顺序

  • 我是否每次都必须检查每一列的数据类型

  • 有更好的方法吗


我使用的数据库是Informix。我使用的是ESQL/C,它是带有嵌入式SQL扩展的旧C。

处理这个问题的最好方法是通过主机变量,这意味着您不需要在值周围加引号。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);
}
#包括“sqlca.h”
#包括“sqlda.h”
#包括“sqltypes.h”
#包括
#包括
#包括
extern int insert_记录(字符*行,常量字符*选项卡名);
int insert_记录(字符*行,常量字符*选项卡名)
{
/*分析线*/
char*pipe=strchr(线“|”);
字符*逗号=行;
int c_计数=0;
int v_计数=0;
while((逗号=strchr(逗号,,)!=0&&逗号管道)
sep=管道;
*sep='\0';
np=sep+1;
sep=strchr(vp,,);
如果(九月!=0)
{
*sep='\0';
vp=sep+1;
}
}
/*使用占位符创建SQL语句*/
/*名称[i]包含条目i的列名;值[i]包含该值*/
$char缓冲区[4096];
char*sql=buffer;
int len=sizeof(缓冲区)-1;
int num=snprintf(sql,len,“插入%s”,tabname);
如果(num=len)
回报率(-2);
如果(num=len)
回报率(-2);
sql+=num;
len-=num;
pad=“(”;
对于(int i=0;i
您需要做一些澄清,其中有很多。您使用的是C,但您是否使用ODBC或ESQL/C进行数据库操作(或其他操作,但这是两种主要的可能性)。输入是否包含您显示的双引号?看起来您有一个列名称列表,用逗号分隔,后跟一个管道,后跟一组列值,也用逗号分隔-正确吗?如果其中一个列值包含逗号,会发生什么情况?你怎么知道这是哪张桌子?还是数据库,来吧?您说“插入或更新”-请解释。@JonathanLeffler…我使用的是ESQL/C。输入不包含双引号,是的,首先是列名,然后是管道,以及相应的列值。请忽略其他逗号。我必须插入或更新的表和数据库是固定的。