ADO.NET来操作Access的sql参数赋值问题(转载)
原文url:http://jeffreyzhao1985.spaces.live.com/blog/cns!FA6B435F09D91418!1889.entry
最近使用ADO.NET来操作Access遇到的问题
有种说法是Access的功能随便用用就够了,于是我也随便用了下。
忽然被一个问题困扰住了,一个存储过程怎么样都执行不对,让人非常的困惑。
最后发现原来是……如果使用OleDbConnection连接Access并使用OleDbCommand + OleDbParameter这样的标准ADO.NET做法,OleDbParameter的name对于传入Access本身是无关的。唯一相关的是Parameter的顺序。
打个比方,一个最简单的表:
CREATE TABLE SampleTable(StrVal1 string, StrVal2 string, StrVal3 string)
使用一个最简单的存储过程INSERT_NEW_STR:
INSERT INTO SampleTable (StrVal1, StrVal2, StrVal3) VALUE (@str1, @str2, @str3);
然后是C#代码:
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=DB.mdb"))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("INSERT_NEW_STR", conn);
cmd.Parameters.Add(new OleDbParameter("@str3", "str3"));
cmd.Parameters.Add(new OleDbParameter("@str1", "str1"));
cmd.Parameters.Add(new OleDbParameter("@str2", "str2"));
cmd.ExecuteNonQuery();
}
猜猜看结果?
结果是:
StrVal1 StrVal2 StrVal3
-----------------------------------------------
str3 str1 str2
原因就在于,每个OleDbParameter的name没有起作用,Access简单的使用参数的顺序来赋给存储过程。当时我遇到的是一个UPDATE,由于传入参数的顺序不对,WHERE Clause总是不会满足,因此总是没有起效果。作了无数次的试验,总算发现了问题。另外,Access对于参数也没有命名要求,会把与字段名无关的标识都认为是参数。也就是说,如果在一个存储过程中一个字段名有一个字母被拼错了,那么它会被作为参数,还是能正确建立这个存储过程。
其实由于Accees比较早,它对于ADO.NET的很多“协议”都无法支持。另外,Access中我一直称为“存储过程”的玩意儿只是“查询”。Access不允许在一个“查询”中使用多条语句,这个已经完全无法胜任几乎所有的开发需要了。再者,由于连接Access时使用的是文件共享方式,其并发数受到了严重的限制,一般十几个连接还行,超过了30个就会有比较难以让人接受的影响了。
因此Access其实已经是个“闹着玩”的玩意儿了,如果不是找不到好的托管服务商,我也不会使用Access。
哦不,如果不是Live Spaces的Gadget无法set/getPreference,我也不会做这个玩意儿。