测试mysql:DAAB MySql支持测试(Proc+DataSet更新)来源: 发布时间:星期四, 2009年2月12日 浏览:182次 评论:0
以前装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 LibraryData Access Application Block基础上加上MySQL支持所以看了下MySQL以及MySql .Net Connector些主要方面使用方法 存储过程 在test库里面建立测试表: 创建测试表TblUser \" align=top>CREATETABLE`test`.`TblUser`( \" align=top>`UserID`INTEGERUNSIGNEDNOTNULLDEFAULTNULLAUTO_INCREMENT, \" align=top>`UserCode`VARCHAR(12)NOTNULL, \" align=top>`UserName`VARCHAR(45), \" align=top>PRIMARYKEY(`UserID`) \" align=top>) \" align=top>ENGINE=InnoDB \" align=top>CHARACTERSETutf8COLLATEutf8_general_ci; 在MySQL AdministratorGUI工具里面在User Administration里为当前操作用户添加对test和系统库mysql权限让用户能创建存储过程 如果是在命令行或者是Query Browser创建存储过程执行下面语句: 创建存储过程SP_QueryUser \" align=top>DELIMITER// \" align=top>CREATEPROCEDUREtest.SP_QueryUser( \" align=top>inUCvarchar(12), \" align=top>inUNvarchar(45)) \" align=top>BEGIN \" align=top>select*fromTblUser \" align=top>whereUserCodelikeUCandUserNamelikeUN; \" align=top>END// 如果是用MySQL Administrator创建存储过程用下面语句: 创建存储过程SP_QueryUser \" align=top>CREATEPROCEDUREtest.SP_QueryUser( \" align=top>inUCvarchar(12), \" align=top>inUNvarchar(45)) \" align=top>BEGIN \" align=top>select*fromTblUser \" align=top>whereUserCodelikeUCandUserNamelikeUN; \" align=top>END 注意: 1. DELIMITER //语句MySQL多个SQL语句/命令的间默认使用;隔开存储过程body里面也要使用;将多个语句分隔开这样如果MySQL将创建存储过程SQL语句使用;分隔然后个个执行就会有语法无法创建存储过程因此我们先使用DELIMITER关键字将默认分隔符修改为//(也可以是其它你认为合适例如?等)这样MySQL才会将存储过程创建语句当作个完整SQL语句执行[Page] 2. 参数参数名是不需要使用参数标志符号例如上面例子UC、UN两个参数名前面并没有加上参数标志符号?如果加上参数标志符号会报语法参数名不需要使用参数标志符号因此注意参数名字别跟表字段名字重名 3. 详细语法参考MySQL官方文档些摘选SQL语法如下: MySQL语法摘选 \" align=top>#generalstatement# \" align=top>declareuid,id; \" align=top>declare ucodevarchar(12); \" align=top>declareunamevarchar(45); \" align=top>id=10; \" align=top>selectUserIDouidfromTblUserwhereUserCode=\'admin\'; \" align=top> \" align=top>#statement# \" align=top>then \" align=top> \" align=top>then \" align=top> \" align=top>end; \" align=top> \" align=top>#statement# \" align=top> \" align=top>whenthen \" align=top> \" align=top>whenthen \" align=top> \" align=top> \" align=top> \" align=top>end; \" align=top> \" align=top>#whilestatement# \" align=top>whiledo \" align=top> \" align=top> endwhile; \" align=top> \" align=top>#cursor# \" align=top>declarerowCount; \" align=top>declaremy_curcursorforselectUserID,UserCode,UserNamefromTblUserorderbyUserCode; \" align=top>openmy_cur; \" align=top>#youneedcontroltheloopcountbyyourself# \" align=top>selectcount(*)orowCountfromTblUser; \" align=top>whilerowCount>0do \" align=top>fetchmy_curouid,ucode,uname; \" align=top>#finishyourtasks# \" align=top> \" align=top>rowCount=rowCount-1 \" align=top>endwhile; \" align=top>closemy_cur; MySQL里面执行存储过程语法为call StoredProcedureName (\'参数1\',\'参数2\')例如上面存储过程为: \" align=top>CallSP_QueryUser(\'%\',\'%\') 用MySql.Data.MySqlClient存储过程方式跟SQL Server样: MySql.Data.MySqlClient存储过程 \" align=top>MySqlConnectionconnection=MySqlConnection(\"Datasource=localhost;UserId=root;Password=123;Database=test;\"); \" align=top>connection.Open; \" align=top>MySqlCommandcommand=MySqlCommand; \" align=top>command.Connection=connection; \" align=top>command.CommandType=CommandType.StoredProcedure; \" align=top>command.CommandText=\"SP_QueryUser\"; \" align=top>command.Parameters.Add(MySqlParameter(\"?UC\",this.TextBox1.Text.Trim+\"%\")); \" align=top>command.Parameters.Add(MySqlParameter(\"?UN\",this.TextBox2.Text.Trim+\"%\" )); \" align=top>MySqlDataAdapteradapter=MySqlDataAdapter(command); \" align=top>DataSetds=DataSet; \" align=top>adapter.Fill(ds); \" align=top>connection.Close; \" align=top> \" align=top>this.GridView1.DataSource=ds; \" align=top>this.GridView1.DataBind; 在Enterprise Library Data Access Application Block里面提供这样方式存储过程: \" align=top>publicvirtualDataSetExecuteDataSet(storedProcedureName,paramsobjectparameterValues) 你不必提供存储过程参数名列表只需要提供object参数值在第次存储过程时DAAB会自动从数据库读取存储过程参数列表并生成DbParameter对象缓存Cache起来后续这个存储过程就从缓存Cache中读取参数列表设置参数值然后向数据库发送执行象SQL ServerSqlDatabase类通过SQL Server系统存储过程sp_procedure_params_row(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 ServerADO.Net驱动完全样使用MySqlCommandBuilder.DeriveParameters(MySqlCommand command)思路方法实现 下面思路方法是我自己写段取存储过程参数名称列表实现思路方法只是种尝试MySqlCommandBuilderDeriveParameters思路方法是通过MySQL接口完成并且会填充参数Direction、Size、Scale等属性 MySQL里面存储过程信息保存在mysql数据库proc表里面param_list字段为参数列表: \" align=top>SELECTparam_listFROMmysql.procwhereproc.name=\'StoredProcedureName\'andproc.db =\'DBName\' param_list是个BLOB类型并且是存储过程创建语句参数括号里面原串因此需要从这个串里面解析出参数名称下面简单用.Net代码举例解析参数名(不解析参数类型) 取MySQL存储过程参数列表C#代码 \" align=top>using; \" align=top>usingMySql.Data.MySqlClient; \" align=top> \" align=top>publicMySqlUtil \">{ \" align=top>publicMySqlUtil \">{ \" align=top>} \" align=top> /**//**//**////<summary> \" align=top>///解析MySQL存储过程参数名列表 \" align=top>///</summary> \" align=top>///<paramname=\"procParam\">mysql数据库proc表字段param_list值</param> \" align=top>///<paramname=\"paramList\">返回参数列表</param> \" align=top>///<s>如果有参数返回true否则返回false</s> \" align=top>publicboolProcParamList(objectprocParam,refMySqlParameterparamList) \">{ \" align=top>boolresult=false; \" align=top> \" align=top>(!object.ReferenceEquals(procParam,null)&&(procParamis)) \">{ \" align=top>//将param_list值转换成串 \" align=top>Param=()procParam; \" align=top>global::.Text.ASCIIEncodingencoding=global::.Text.ASCIIEncoding; \" align=top>strParam=encoding.GetString(Param); \" align=top>//移除回车换行TAB等特殊控制 \" align=top>strParam=strParam.Replace(\"\\r\",\"\").Replace(\"\\n\" ,\"\").Replace(\"\\t\",\"\").Trim; \" align=top>//参数列表 \" align=top>.gif' />Params=strParam.Split(\',\'); \" align=top>(!object.ReferenceEquals(.gif' />Params,null)&&.gif' />Params.Length>0) \">{ \" align=top>//用于过滤掉参数输入、输出类型 \" align=top>tokens=\"[IN][OUT][INOUT]\"; \" align=top>global::.Collections.ArrayList.gif' />List=global::.Collections.ArrayList(.gif' />Params.Length); \" align=top>MySqlParametermysqlParam; \" align=top>oneParam; \" align=top> param=\"\"; \" align=top>for(paramCount=0;paramCount<.gif' />Params.Length;paramCount) \">{ \" align=top>//param格式类似于:IN/OUT/INOUTparamNameVarchar(30)/INT等 \" align=top>param=.gif' />Params[paramCount]; \" align=top>(!.IsNullOrEmpty(param)&¶m.Trim.Length>0) \">{ \" align=top>oneParam =param.Split(\'\'); \" align=top>for(i=0;i<param.Length;i) \">{ \" align=top>//是否是空或者是参数Direction关键字(IN/OUT/INOUT)? \" align=top>(.IsNullOrEmpty(oneParam[i])||oneParam[i].Trim\"\"||tokens.IndexOf(\"[\"+oneParam[i].Trim.ToUpper+\"]\")>0) \" align=top>continue; \" align=top>//得到参数名 \" align=top> mysqlParam=MySqlParameter; \" align=top>mysqlParam.ParameterName=\"?\"+oneParam[i].Trim; \" align=top>.gif' />List.Add(mysqlParam); \" align=top>result=true; \" align=top>; \" align=top>} \" align=top>} \" align=top>} \" align=top>paramList=(MySqlParameter).gif' />List.ToArray(typeof(MySqlParameter)); \" align=top>} \" align=top>} \" align=top> \" align=top>result; \" align=top>} \" align=top>} \" align=top> \" align=top>//上面思路方法举例代码 \" align=top>//取存储过程SP_QueryUser参数 \" align=top>MySqlConnectionconnection= MySqlConnection(\"Datasource=localhost;UserId=root;Password=123;Database=mysql;\"); \" align=top>connection.Open; \" align=top>MySqlCommandcommand=MySqlCommand(\"selectparam_listfrommysql.procwhereproc.name=?SPNameandproc.DB=?DBName\",connection); \" align=top>command.Parameters.Add(MySqlParameter(\"?SPName\",\"SP_QueryUser\")); \" align=top>command.Parameters.Add(MySqlParameter(\"?DBName\",\"test\")); \" align=top>MySqlDataAdapteradapter=MySqlDataAdapter(command); \" align=top>DataSetds=DataSet; \" align=top>adapter.Fill(ds); \" align=top>connection.Close; \" align=top> \" align=top>//解析参数列表 \" align=top>(ds.Tables.Count>0&&ds.Tables[0].Rows.Count>0) \">{ \" align=top>MySqlParameterparamList =null; \" align=top>(MySqlUtil.ProcParamList(ds.Tables[0].Rows[0][\"param_list\"],refparamList)) \">{ \" align=top>s=\"\"; \" align=top>foreach(MySqlParameterparaminparamList) \">{ \" align=top>s=s+param.ParameterName+\"\"; \" align=top>} \" align=top>this.TextBox1.Text=s; \" align=top>} \" align=top>} DataSet Update 上面建表TblUser中有个自增类型字段为了简化DataSet Update测试建立了另外个测试表TblItem: 创建测试表TblItem \" align=top>CREATETABLE`test`.`TblItem`( \" align=top>`ItemID`VARCHAR(36)NOTNULL, \" align=top>`ItemNo`VARCHAR(20)NOTNULL, \" align=top>`ItemName`VARCHAR(60), \" align=top>PRIMARYKEY(`ItemID`) \" align=top>) \" align=top>ENGINE=InnoDB \" align=top>CHARACTERSETutf8COLLATEutf8_general_ci; DataSet Update测试代码如下整个代码跟Sql Server数据库写法上没有差别测试过程中开始在adapter.Update思路方法后稍微停滞段时间然后出现个\"Server shutdown in progress\"异常把MySql些内存Buffer适当调大些重起MySql服务再进行测试就OK了 DataSet Update简单测试 \" align=top>//取DataSet \" align=top>MySqlConnectionconnection=MySqlConnection(\"Datasource=localhost;UserId=root;Password=123;Database=test;\"); \" align=top>connection.Open; \" align=top>sql=\"select*fromtblitem\"; \" align=top>MySqlCommandcommand=MySqlCommand(sql,connection); \" align=top>MySqlDataAdapteradapter=MySqlDataAdapter(command); \" align=top>DataSetds=DataSet; \" align=top>adapter.Fill(ds); \" align=top> \" align=top>//修改数据 \" align=top>DataTabletable=ds.Tables[0]; \" align=top>//修改行 \" align=top>(table.Rows.Count>=1) \" align=top>table.Rows[0][\"ItemName\"]=table.Rows[0][\"ItemName\"].+ \"_o\"; \" align=top>//删除行 \" align=top>(table.Rows.Count>=2) \" align=top>table.Rows[1].Delete; \" align=top>//插入两行 \" align=top>DataRowrow; \" align=top>row=table.NewRow; \" align=top>row[\"ItemID\"]=Guid.NewGuid..ToUpper; \" align=top>row[\"ItemNo\"]=\"Item-\"+DateTime.Now.AddDays(-2).(\"yyMMddHHmmss\"); \" align=top>row[\"ItemName\"]=\"Item-\"+DateTime.Now.AddDays(-2).(\"yyMMddHHmmss\"); \" align=top>table.Rows.Add(row); \" align=top>row=table.NewRow; \" align=top>row[\"ItemID\"]=Guid.NewGuid..ToUpper; \" align=top>row[\"ItemNo\"]=\"Item-\"+DateTime.Now.AddDays(-1).(\" yyMMddHHmmss\"); \" align=top>row[\"ItemName\"]=\"Item-\"+DateTime.Now.AddDays(-1).(\"yyMMddHHmmss\"); \" align=top>table.Rows.Add(row); \" align=top> \" align=top>//更新数据 \" align=top>//IsolationLevel.ReadUncommitted \" align=top>MySqlTransactiontran=connection.BeginTransaction; \" align=top>try \">{ \" align=top>MySqlParameterparam; \" align=top>MySqlCommandupdate=MySqlCommand(\"updatetest.tblitemtblitem.ItemNo=?ItemNo,tblitem.ItemName=?ItemNamewheretblitem.ItemID=?ItemID\",connection); \" align=top>param=MySqlParameter(\"?ItemNo\",MySqlDbType.VarChar,18,ParameterDirection.Input,false,0,0,\"ItemNo\",DataRowVersion.Current,null); \" align=top>update.Parameters.Add(param); \" align=top>param=MySqlParameter(\"?ItemName\",MySqlDbType.VarChar,60,ParameterDirection.Input,true,0,0,\"ItemName\",DataRowVersion.Current,null); \" align=top>update.Parameters.Add(param); \" align=top>param=MySqlParameter(\"?ItemID\",MySqlDbType.VarChar,36,ParameterDirection.Input,false,0,0,\"ItemID\",DataRowVersion.Original,null); \" align=top>update.Parameters.Add(param); \" align=top>update.Transaction=tran; \" align=top> \" align=top>MySqlCommandinsert=MySqlCommand(\"insertotest.tblitem(ItemID,ItemNo,ItemName)values(?ItemID,?ItemNo,?ItemName)\",connection); \" align=top>param=MySqlParameter(\"?ItemID\",MySqlDbType.VarChar,36,ParameterDirection.Input,false,0,0,\"ItemID\",DataRowVersion.Current,null); \" align=top>insert.Parameters.Add(param); \" align=top>param= MySqlParameter(\"?ItemNo\",MySqlDbType.VarChar,18,ParameterDirection.Input,false,0,0,\"ItemNo\",DataRowVersion.Current,null); \" align=top>insert.Parameters.Add(param); \" align=top>param=MySqlParameter(\"?ItemName\",MySqlDbType.VarChar,60,ParameterDirection.Input,true,0,0,\"ItemName\",DataRowVersion.Current,null); \" align=top>insert.Parameters.Add(param); \" align=top>insert.Transaction=tran; \" align=top> \" align=top>MySqlCommanddelete=MySqlCommand(\"deletefromtest.tblitemwheretblitem.ItemID=?ItemID\",connection); \" align=top>param=MySqlParameter(\"?ItemID\",MySqlDbType.VarChar,36,ParameterDirection.Input,false,0,0,\"ItemID\",DataRowVersion.Original,null); \" align=top>delete.Parameters.Add(param); \" align=top>delete.Transaction=tran; \" align=top> \" align=top>adapter.UpdateCommand=update; \" align=top>adapter.InsertCommand=insert; \" align=top>adapter.DeleteCommand=delete; \" align=top> \" align=top>adapter.Update(table); \" align=top>tran.Commit; \" align=top>} \" align=top>catch \">{ \" align=top>tran.Rollback; \" align=top>} \" align=top> \" align=top>//显示更新后数据 \" align=top>ds.Tables.Clear; \" align=top>adapter.Fill(ds); \" align=top>connection.Close; \" align=top> \" align=top>this.GridView1.DataSource=ds; \" align=top>this.GridView1.DataBind; 有了上面这些了解就可以从Enterprise Library Data Access Application BlockDatabase类继承实现个MySqlDatabase类了并且非常简单 0
相关文章读者评论发表评论 |