C语言 表单数据库查询从输入



在我的C程序中,我接收的输入格式为

     "name,age,salary|Richard,35,10000"

现在我想从这个输入中插入和更新查询。

我使用strtok_rstrtok用于此目的。

但是我的问题是,在插入或更新时,我必须在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 = '';
        np = sep + 1;
        sep = strchr(vp, ',');
        if (sep != 0)
        {
            *sep = '';
            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] = '';
    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);
}

最新更新