Richie

Sometimes at night when I look up at the stars, and see the whole sky just laid out there, don't you think I ain't remembering it all. I still got dreams like anybody else, and ever so often, I am thinking about how things might of been. And then, all of a sudden, I'm forty, fifty, sixty years old, you know?

[ MySQL ] DAAB MySql支持测试(Proc+DataSet更新) 5.0.27+.Net Connector 5.0.2beta

    以前装的MySQL 5.0.24a版本,因为有些问题,所以卸载掉重新装了5.0.27,感觉比5.0.24a那个版本要稳定,测试一下,在5.0.24a上存在的问题已经没有了。另外,以前用的ByteFX.Data,这次看到MySQL .Net Connector有了5.0.2版本,改用这个,毕竟官方正式的驱动要更可靠。
    参考:MySQL的使用 MySQL 5.0.24a + ByteFX.Data 0.76,里面提到的两个问题,在5.0.27下面不需要再处理。
    另外,使用MySQL 5.0.27 + MySQL .Net Connector 5.0.2 beta需要注意的地方,就是参数标志符号为?,而不是@。例如:select * from TblUser where UserID=?UID。在MySQL的使用 MySQL 5.0.24a + ByteFX.Data 0.76中参数标志符号使用的就是@。
    因为想用MySQL写点东西,要在Enterprise Library的Data Access Application Block基础上加上MySQL支持,所以看了下MySQL以及MySql .Net Connector一些主要方面的用法。

    存储过程
    在test库里面建立测试表:
创建测试表TblUser

    在MySQL Administrator的GUI工具里面,在User Administration里为当前操作的用户添加对test和系统库mysql的权限,让用户能创建存储过程。

    如果是在命令行或者是Query Browser创建存储过程,执行下面的语句:
创建存储过程SP_QueryUser
    如果是用MySQL Administrator创建存储过程,用下面的语句:
创建存储过程SP_QueryUser
    注意:
    1. DELIMITER //语句。MySQL的多个SQL语句/命令之间,默认使用;隔开,存储过程的body里面也要使用;将多个语句分隔开,这样,如果MySQL将创建存储过程的SQL语句使用;分隔,然后一个一个执行,就会有语法错误,无法创建存储过程。因此我们先使用DELIMITER关键字,将默认的分隔符修改为//(也可以是其它你认为合适的字符,例如?等),这样MySQL才会将存储过程的创建语句当作一个完整的SQL语句执行。
    2. 参数。参数名是不需要使用参数标志符号的,例如上面的例子,UC、UN两个参数名前面并没有加上参数标志符号?,如果加上参数标志符号会报语法错误。因为参数名不需要使用参数标志符号,因此注意参数名字别跟表的字段名字重名。
    3. 详细的语法,参考MySQL官方文档。一些摘选的SQL语法如下:
MySQL语法摘选

    MySQL里面执行存储过程的语法为call StoredProcedureName ('参数1','参数2'),例如调用上面的存储过程为:
Call SP_QueryUser('%','%')
    用MySql.Data.MySqlClient调用存储过程,方式跟SQL Server一样:
MySql.Data.MySqlClient调用存储过程

    在Enterprise Library Data Access Application Block里面,提供这样的方式调用存储过程:
public virtual DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
    你不必提供存储过程参数名列表,只需要提供object[]的参数值,在第一次调用存储过程时,DAAB会自动从数据库读取存储过程参数列表,并生成DbParameter对象缓存起来,后续调用这个存储过程就从缓存中读取参数列表,设置参数值,然后向数据库发送执行。象SQL Server的SqlDatabase类,通过调用SQL Server系统存储过程sp_procedure_params_rowset(SQL 2005中通过调用sp_procedure_params_managed)实现。其实SQL Server的存储过程完全可以使用StoredProcedureName '参数1','参数2'的方式执行,但这种方式下需要将CommandType设成CommandType.Text,估计这样可能会导致数据库驱动并不是采用存储过程的方式执行命令,可能会造成存储过程的一些优化方面失效(直接把参数值拼到SQL里面,估计会以ad hoc方式处理;使用存储过程名带参数的方式,估计以RPC方式执行,但数据库驱动以及数据库服务器是以普通的RPC还是存储过程的方式对待不得而知)。当然,这个结论只是个人猜测,并没有去验证。
    不管怎样,按照MS的推荐方式使用是一种好的选择,因此在DAAB实现MySqlDatabase时也保持这样一种机制,这样就需要在MySQL中获取存储过程的参数列表。这点跟Oracle、Sql Server的ADO.Net驱动完全一样,使用MySqlCommandBuilder.DeriveParameters(MySqlCommand command)方法实现。
    下面的方法是我自己写的一段取存储过程参数名称列表的实现方法,只是一种尝试。MySqlCommandBuilder的DeriveParameters方法是通过调用MySQL接口完成的,并且会填充参数的Direction、Size、Scale等属性。
    MySQL里面存储过程信息保存在mysql数据库的proc表里面,param_list字段为参数列表:
SELECT param_list FROM mysql.proc where proc.name='StoredProcedureName' and proc.db='DBName'
    param_list是一个BLOB类型,并且是存储过程创建语句的参数括号里面的原字符串,因此需要从这个字符串里面解析出参数名称。下面简单的用.Net代码示例解析参数名(不解析参数类型)。
取MySQL存储过程参数列表C#代码

    DataSet Update
    上面建的表TblUser中有一个自增类型的字段,为了简化DataSet Update的测试,建立了另外一个测试表TblItem:
创建测试表TblItem

    DataSet Update的测试代码如下,整个代码跟Sql Server数据库写法上没有差别。测试过程中一开始在调用adapter.Update()方法后稍微停滞一段时间,然后出现一个"Server shutdown in progress"异常,把MySql的一些内存Buffer适当调大一些,重起MySql服务再进行测试就OK了。
DataSet Update简单测试

    有了上面这些了解,就可以从Enterprise Library Data Access Application Block的Database类继承,实现一个MySqlDatabase类了,并且非常简单。

posted on 2006-12-26 00:13  riccc  阅读(2001)  评论(0编辑  收藏  举报

导航