ADO.NET MSAccess更新失败,因为带参数的WHERE子句不会命中

时间:2016-02-10 10:55:49

标签: c# ado.net oledbcommand

我似乎有一个奇怪的问题,我无法弄清楚我做错了什么。 我的代码应该更新记录,但不会。

IDbCommand cmd = ((IConnectionProvider) _Tender).Connection.CreateCommand();

if(_ID == null)
{
    cmd.CommandText = "INSERT INTO ELEMENTS (ID, HOP, HMODE, HSORT, HFLAGS, KPARENT, TEMPLATE, NUMV, NAMV, TITLE, TXTV, RESERVED, CDATA, VDATA) VALUES (@id, @hop, @hmode, @hsort, @hflags, @kparent, @template, @numv, @namv, @title, @txtv, @reserved, @cdata, @vdata)";
    _ID = _CreateID();
    _Tender.Factory._Cache.Add(_ID, this);
}
else
{
    cmd.CommandText = "UPDATE ELEMENTS SET HOP = @hop, HMODE = @hmode, HSORT = @hsort, HFLAGS = @hflags, KPARENT = @kparent, TEMPLATE = @template, NUMV = @numv, NAMV = @namv, TITLE = @title, TXTV = @txtv, RESERVED = @reserved, CDATA = @cdata, VDATA = @vdata WHERE ID = @id";
}

cmd.AddParameter("@id", _ID);
cmd.AddParameter("@hop", _ActualType);
cmd.AddParameter("@hmode", _Mode);
cmd.AddParameter("@hsort", _Sort);
cmd.AddParameter("@hflags", _Flags);
cmd.AddParameter("@kparent", ((_Parent == null) ? "" : _Parent.ID));
cmd.AddParameter("@template", ((_Template == null) ? "" : _Template.ToString()));
cmd.AddParameter("@numv", _Number);
cmd.AddParameter("@namv", _Name);
cmd.AddParameter("@title", _Title);
cmd.AddParameter("@txtv", _Text);
cmd.AddParameter("@reserved", _Reserved);
cmd.AddParameter("@cdata", _CData);
cmd.AddParameter("@vdata", _VData);

int v = cmd.ExecuteNonQuery();

INSERT部分工作得很好。 UPDATE部分不会因为我无法理解的原因更新记录。最后一个语句中的v为0。

如果我把命令文本放在那样:

cmd.CommandText = "UPDATE ELEMENTS SET HOP = @hop, HMODE = @hmode, HSORT = @hsort, HFLAGS = @hflags, KPARENT = @kparent, TEMPLATE = @template, NUMV = @numv, NAMV = @namv, TITLE = @title, TXTV = @txtv, RESERVED = @reserved, CDATA = @cdata, VDATA = @vdata WHERE ID = '" + _ID + "'";

(不使用WHERE子句中的绑定变量)它可以工作(v == 1)。

我出于可移植性的原因使用接口,为方便起见,我编写了AddParameter()扩展方法。 _ID是一个字母数字值,如“g5fRRa3P89gX”或其他东西。

_Connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";");

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, DbType type, object value)
{
    IDbDataParameter p = cmd.CreateParameter();

    p.DbType = type;
    p.ParameterName = name;
    p.Value = value;

    if(value is string)
    {
        p.Size = ((string) value).Length;
        if(p.Size == 0) { p.Size = 1; }
    }
    else
    {
        p.Size = sizeof(int);
    }

    cmd.Parameters.Add(p);

    return p;
}

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, string value)
{
    return AddParameter(cmd, name, DbType.String, value);
}

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, int value)
{
    return AddParameter(cmd, name, DbType.Int32, value);
}

有没有人对此有所了解? 谢谢,Alex。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,并没有像我想象的那样尴尬。似乎驱动程序根本不支持命名的参数。这有点奇怪,因为您可以定义和使用它们,但显然它们将始终按照它们添加到命令的顺序应用,而忽略它们的名称。 因此,当最后分配@id参数时,代码将适用于UPDATE部分...