分类: Mysql/postgreSQL
2008-05-12 15:15:10
在本节中,概要介绍了按功能分类的ODBC子程序。
关于全部ODBC API参考,请参见ODBC程序员参考,。
应用程序可以调用SQLGetInfo函数来获得关于MyODBC的一致性信息。为了获得驱动程序对特定函数的支持信息,应用程序可调用SQLGetFunctions。
注释: 为了向后兼容,MyODBC 3.51驱动程序支持所有已不使用的函数。
在下面的表各中,按任务分组列出了MyODBC API调用:
连接到数据源:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLAllocHandle |
No |
Yes |
ISO 92 |
获取环境、连接、语句或描述符句柄。 |
SQLConnect |
Yes |
Yes |
ISO 92 |
按数据源名、用户ID和密码连接到特定驱动程序。 |
SQLDriverConnect |
Yes |
Yes |
ODBC |
通过连接字符串,或驱动管理器和驱动显示对话框发出的请求,连接到特定驱动程序。 |
SQLAllocEnv |
Yes |
Yes |
Deprecated |
获得驱动程序分配的环境句柄。 |
SQLAllocConnect |
Yes |
Yes |
Deprecated |
获取连接句柄。 |
获取关于驱动程序和数据源的信息:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLDataSources |
No |
No |
ISO 92 |
返回可用数据源的列表,由驱动管理器处理。 |
SQLDrivers |
No |
No |
ODBC |
返回已安装驱动程序和器属性的列表,由驱动管理器处理。 |
SQLGetInfo |
Yes |
Yes |
ISO 92 |
返回关于特定驱动程序和数据源的信息。 |
SQLGetFunctions |
Yes |
Yes |
ISO 92 |
返回支持的驱动函数。 |
SQLGetTypeInfo |
Yes |
Yes |
ISO 92 |
返回关于所支持数据类型的信息。 |
设置并检索驱动属性:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLSetConnectAttr |
No |
Yes |
ISO 92 |
设置连接属性。 |
SQLGetConnectAttr |
No |
Yes |
ISO 92 |
返回连接属性的值。 |
SQLSetConnectOption |
Yes |
Yes |
Deprecated |
设置连接选项。 |
SQLGetConnectOption |
Yes |
Yes |
Deprecated |
返回连接选项的值。 |
SQLSetEnvAttr |
No |
Yes |
ISO 92 |
设置环境属性。 |
SQLGetEnvAttr |
No |
Yes |
ISO 92 |
返回环境属性的值。 |
SQLSetStmtAttr |
No |
Yes |
ISO 92 |
设置语句属性。 |
SQLGetStmtAttr |
No |
Yes |
ISO 92 |
返回语句属性的值。 |
SQLSetStmtOption |
Yes |
Yes |
Deprecated |
设置语句选项。 |
SQLGetStmtOption |
Yes |
Yes |
Deprecated |
返回语句选项的值。 |
准备SQL请求:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLAllocStmt |
Yes |
Yes |
Deprecated |
分配语句句柄。 |
SQLPrepare |
Yes |
Yes |
ISO 92 |
准备随后执行的SQL语句。 |
SQLBindParameter |
Yes |
Yes |
ODBC |
为SQL语句中的参数分配存储器。 |
SQLGetCursorName |
Yes |
Yes |
ISO 92 |
返回与语句句柄相关的光标名。 |
SQLSetCursorName |
Yes |
Yes |
ISO 92 |
指定光标名。 |
SQLSetScrollOptions |
Yes |
Yes |
ODBC |
设置控制光标行为的选项。 |
提交请求:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLExecute |
Yes |
Yes |
ISO 92 |
执行准备好的语句。 |
SQLExecDirect |
Yes |
Yes |
ISO 92 |
执行语句。 |
SQLNativeSql |
Yes |
Yes |
ODBC |
返回由驱动程序翻译的SQL语句的文本。 |
SQLDescribeParam |
Yes |
Yes |
ODBC |
返回语句中特定参数的描述。 |
SQLNumParams |
Yes |
Yes |
ISO 92 |
返回语句中的参数数目。 |
SQLParamData |
Yes |
Yes |
ISO 92 |
与SQLPutData一起使用,以便在执行时提供参数。(对于长数据值很有用)。 |
SQLPutData |
Yes |
Yes |
ISO 92 |
发送某一参数数据值的部分或全部。(对于长数据值很有用)。 |
检索结果以及关于结果的信息:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLRowCount |
Yes |
Yes |
ISO 92 |
返回插入、更新或删除请求影响的行数。 |
SQLNumResultCols |
Yes |
Yes |
ISO 92 |
返回结果集中的列数。 |
SQLDescribeCol |
Yes |
Yes |
ISO 92 |
描述结果集中的列。 |
SQLColAttribute |
No |
Yes |
ISO 92 |
描述结果集中的某1列的属性。 |
SQLColAttributes |
Yes |
Yes |
Deprecated |
描述结果集中的某1列的多个属性。 |
SQLFetch |
Yes |
Yes |
ISO 92 |
返回多个结果行。 |
SQLFetchScroll |
No |
Yes |
ISO 92 |
返回可滚动结果行。 |
SQLExtendedFetch |
Yes |
Yes |
Deprecated |
返回可滚动结果行。 |
SQLSetPos |
Yes |
Yes |
ODBC |
将光标定为在获取的数据块中,允许应用程序更新行集合中的数据,或更新或删除结果集中的数据。 |
SQLBulkOperations |
No |
Yes |
ODBC |
执行批量插入和批量书签操作,包括更新、删除和按书签获取。 |
检索错误和诊断信息:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLError |
Yes |
Yes |
Deprecated |
返回额外的错误或状态信息。 |
SQLGetDiagField |
Yes |
Yes |
ISO 92 |
返回额外的诊断信息(诊断性数据结构的单个字段)。 |
SQLGetDiagRec |
Yes |
Yes |
ISO 92 |
返回额外的诊断信息(诊断性数据结构的多个字段)。 |
获取关于数据源的系统表(目录函数)条目的信息:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLColumnPrivileges |
Yes |
Yes |
ODBC |
返回关于一个或多个表的列和相关属性的列表。 |
SQLColumns |
Yes |
Yes |
X/Open |
返回指定表中列名的列表。 |
SQLForeignKeys |
Yes |
Yes |
ODBC |
在指定表中如果存在外键,返回构成外键的列名列表。 |
SQLPrimaryKeys |
Yes |
Yes |
ODBC |
返回构成某1表的主键的列名列表。 |
SQLSpecialColumns |
Yes |
Yes |
X/Open |
返回关于最佳列集合的信息,该列集合唯一地指明了指定表中的行,或当某1事务更新了行中的任何值时自动更新的列。 |
SQLStatistics |
Yes |
Yes |
ISO 92 |
返回关于单个表的统计信息,以及与表相关的索引列表。 |
SQLTablePrivileges |
Yes |
Yes |
ODBC |
返回表列表,以及与各表相关的权限。 |
SQLTables |
Yes |
Yes |
X/Open |
返回存储在特定数据源内的表名列表。 |
执行事务:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLTransact |
Yes |
Yes |
Deprecated |
提交或回滚事务。 |
SQLEndTran |
No |
Yes |
ISO 92 |
提交或回滚事务。 |
中止语句:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLFreeStmt |
Yes |
Yes |
ISO 92 |
结束语句处理,舍弃未决结果,并释放与语句句柄相关的所有资源(可选)。 |
SQLCloseCursor |
Yes |
Yes |
ISO 92 |
关闭在语句句柄上打开的指针。 |
SQLCancel |
Yes |
Yes |
ISO 92 |
取消SQL语句。 |
中止连接:
函数名 |
MyODBC |
MyODBC |
一致性 |
目的 |
|
2.50 |
3.51 |
|
|
SQLDisconnect |
Yes |
Yes |
ISO 92 |
关闭连接。 |
SQLFreeHandle |
No |
Yes |
ISO 92 |
释放环境、连接、语句或描述符句柄。 |
SQLFreeConnect |
Yes |
Yes |
Deprecated |
释放连接句柄。 |
SQLFreeEnv |
Yes |
Yes |
Deprecated |
释放连接句柄。 |
在下表中,介绍了驱动程序将服务器数据类型映射为默认SQL和C数据类型的方法:
值 |
SQL类型 |
C类型 |
bit |
SQL_BIT |
SQL_C_BIT |
tinyint |
SQL_TINYINT |
SQL_C_STINYINT |
tinyint unsigned |
SQL_TINYINT |
SQL_C_UTINYINT |
bigint |
SQL_BIGINT |
SQL_C_SBIGINT |
bigint unsigned |
SQL_BIGINT |
SQL_C_UBIGINT |
long varbinary |
SQL_LONGVARBINARY |
SQL_C_BINARY |
blob |
SQL_LONGVARBINARY |
SQL_C_BINARY |
longblob |
SQL_LONGVARBINARY |
SQL_C_BINARY |
tinyblob |
SQL_LONGVARBINARY |
SQL_C_BINARY |
mediumblob |
SQL_LONGVARBINARY |
SQL_C_BINARY |
long varchar |
SQL_LONGVARCHAR |
SQL_C_CHAR |
text |
SQL_LONGVARCHAR |
SQL_C_CHAR |
mediumtext |
SQL_LONGVARCHAR |
SQL_C_CHAR |
char |
SQL_CHAR |
SQL_C_CHAR |
numeric |
SQL_NUMERIC |
SQL_C_CHAR |
decimal |
SQL_DECIMAL |
SQL_C_CHAR |
integer |
SQL_INTEGER |
SQL_C_SLONG |
integer unsigned |
SQL_INTEGER |
SQL_C_ULONG |
int |
SQL_INTEGER |
SQL_C_SLONG |
int unsigned |
SQL_INTEGER |
SQL_C_ULONG |
mediumint |
SQL_INTEGER |
SQL_C_SLONG |
mediumint unsigned |
SQL_INTEGER |
SQL_C_ULONG |
smallint |
SQL_SMALLINT |
SQL_C_SSHORT |
smallint unsigned |
SQL_SMALLINT |
SQL_C_USHORT |
real |
SQL_FLOAT |
SQL_C_DOUBLE |
double |
SQL_FLOAT |
SQL_C_DOUBLE |
float |
SQL_REAL |
SQL_C_FLOAT |
double precision |
SQL_DOUBLE |
SQL_C_DOUBLE |
date |
SQL_DATE |
SQL_C_DATE |
time |
SQL_TIME |
SQL_C_TIME |
year |
SQL_SMALLINT |
SQL_C_SHORT |
datetime |
SQL_TIMESTAMP |
SQL_C_TIMESTAMP |
timestamp |
SQL_TIMESTAMP |
SQL_C_TIMESTAMP |
text |
SQL_VARCHAR |
SQL_C_CHAR |
varchar |
SQL_VARCHAR |
SQL_C_CHAR |
enum |
SQL_VARCHAR |
SQL_C_CHAR |
set |
SQL_VARCHAR |
SQL_C_CHAR |
bit |
SQL_CHAR |
SQL_C_CHAR |
bool |
SQL_CHAR |
SQL_C_CHAR |
在下表中,列出了驱动程序返回的除服务器错误之外的错误代码列表:
本机代码 |
SQLSTATE 2 |
SQLSTATE 3 |
错误消息 |
500 |
01000 |
01000 |
一般警告 |
501 |
01004 |
01004 |
字符串数据,右截 |
502 |
01S02 |
01S02 |
选项值被更改 |
503 |
01S03 |
01S03 |
未更新/删除行 |
504 |
01S04 |
01S04 |
更新/删除了1个以上的行 |
505 |
01S06 |
01S06 |
在结果集合返回第1个行集合之前视图获取数据。 |
506 |
07001 |
07002 |
对于所有参数,未使用SQLBindParameter。 |
507 |
07005 |
07005 |
精制语句不符合光标规范 |
508 |
07009 |
07009 |
无效的描述符索引。 |
509 |
08002 |
08002 |
连接名正在使用。 |
510 |
08003 |
08003 |
连接不存在。 |
511 |
24000 |
24000 |
无效的光标状态。 |
512 |
25000 |
25000 |
无效的事务状态。 |
513 |
25S01 |
25S01 |
事务状态未知。 |
514 |
34000 |
34000 |
无效光标名。 |
515 |
S1000 |
HY000 |
一般的驱动程序定义错误。 |
516 |
S1001 |
HY001 |
内存分配错误。 |
517 |
S1002 |
HY002 |
无效的列编号。 |
518 |
S1003 |
HY003 |
无效的应用缓冲类型。 |
519 |
S1004 |
HY004 |
无效的SQL数据类型。 |
520 |
S1009 |
HY009 |
空指针的无效使用。 |
521 |
S1010 |
HY010 |
函数顺序错误。 |
522 |
S1011 |
HY011 |
现在无法设置属性。 |
523 |
S1012 |
HY012 |
无效的事务操作码。 |
524 |
S1013 |
HY013 |
内存管理错误。 |
525 |
S1015 |
HY015 |
无可用的光标名。 |
526 |
S1024 |
HY024 |
无效的属性值。 |
527 |
S1090 |
HY090 |
无效字符串或缓冲长度。 |
528 |
S1091 |
HY091 |
无效的描述符字段标识符。 |
529 |
S1092 |
HY092 |
无效的属性/选项标识符。 |
530 |
S1093 |
HY093 |
无效的参数编号。 |
531 |
S1095 |
HY095 |
函数类型超出范围。 |
532 |
S1106 |
HY106 |
获取类型超出范围。 |
533 |
S1117 |
HY117 |
行值超出范围。 |
534 |
S1109 |
HY109 |
无效的光标位置。 |
535 |
S1C00 |
HYC00 |
可选特性未实施。 |
0 |
21S01 |
21S01 |
列计数与值计数不匹配。 |
0 |
23000 |
23000 |
完整性约束违反。 |
0 |
42000 |
42000 |
语法错误或访问冲突。 |
0 |
42S02 |
42S02 |
未发现基本表或视图。 |
0 |
42S12 |
42S12 |
未发现索引。 |
0 |
42S21 |
42S21 |
列已存在。 |
0 |
42S22 |
42S22 |
未发现列。 |
0 |
08S01 |
08S01 |
通信链接失败。 |
在下面的ADO(ActiveX数据对象)示例中,创建了表my_ado,并演示了rs.addNew、rs.delete和rs.update的用法。
Private Sub myodbc_ado_Click()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Dim sql As String
'connect to MySQL server using MySQL ODBC 3.51 Driver(使用MySQL ODBC 3.51驱动程序连接到MySQL服务器)
Set conn = New ADODB.Connection
conn.ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};"_
& "SERVER=localhost;"_
& " DATABASE=test;"_
& "UID=venu;PWD=venu; OPTION=3"
conn.Open
'create table(创建表)
conn.Execute "DROP TABLE IF EXISTS my_ado"
conn.Execute "CREATE TABLE my_ado(id int not null primary key, name varchar(20)," _
& "txt text, dt date, tm time, ts timestamp)"
'direct insert(直接插入)
conn.Execute "INSERT INTO my_ado(id,name,txt) values(1,100,'venu')"
conn.Execute "INSERT INTO my_ado(id,name,txt) values(2,200,'MySQL')"
conn.Execute "INSERT INTO my_ado(id,name,txt) values(3,300,'Delete')"
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseServer
'fetch the initial table ..(获取初始表…)
rs.Open "SELECT * FROM my_ado", conn
Debug.Print rs.RecordCount
rs.MoveFirst
Debug.Print String(50, "-") & "Initial my_ado Result Set " & String(50, "-")
For Each fld In rs.Fields
Debug.Print fld.Name,
Next
Debug.Print
Do Until rs.EOF
For Each fld In rs.Fields
Debug.Print fld.Value,
Next
rs.MoveNext
Debug.Print
Loop
rs.Close
'rs insert(rs插入)
rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
rs.AddNew
rs!Name = "Monty"
rs!txt = "Insert row"
rs.Update
rs.Close
'rs update(rs更新)
rs.Open "SELECT * FROM my_ado"
rs!Name = "update"
rs!txt = "updated-row"
rs.Update
rs.Close
'rs update second time..(rs更新第2次…)
rs.Open "SELECT * FROM my_ado"
rs!Name = "update"
rs!txt = "updated-second-time"
rs.Update
rs.Close
'rs delete(rs删除)
rs.Open "SELECT * FROM my_ado"
rs.MoveNext
rs.MoveNext
rs.Delete
rs.Close
'fetch the updated table ..(获取更新的表…)
rs.Open "SELECT * FROM my_ado", conn
Debug.Print rs.RecordCount
rs.MoveFirst
Debug.Print String(50, "-") & "Updated my_ado Result Set " & String(50, "-")
For Each fld In rs.Fields
Debug.Print fld.Name,
Next
Debug.Print
Do Until rs.EOF
For Each fld In rs.Fields
Debug.Print fld.Value,
Next
rs.MoveNext
Debug.Print
Loop
rs.Close
conn.Close
End Sub
Private Sub myodbc_dao_Click()
Dim ws As Workspace
Dim conn As Connection
Dim queryDef As queryDef
Dim str As String
'connect to MySQL server using MySQL ODBC 3.51 Driver(使用MySQL ODBC 3.51驱动程序连接到MySQL)
Set ws = DBEngine.CreateWorkspace("", "venu", "venu", dbUseODBC)
str = "odbc;DRIVER={MySQL ODBC 3.51 Driver};"_
& "SERVER=localhost;"_
& " DATABASE=test;"_
& "UID=venu;PWD=venu; OPTION=3"
Set conn = ws.OpenConnection("test", dbDriverNoPrompt, False, str)
'Create table my_dao(创建表my_dao)
Set queryDef = conn.CreateQueryDef("", "drop table if exists my_dao")
queryDef.Execute
Set queryDef = conn.CreateQueryDef("", "create table my_dao(Id INT AUTO_INCREMENT PRIMARY KEY, " _
& "Ts TIMESTAMP(14) NOT NULL, Name varchar(20), Id2 INT)")
queryDef.Execute
'Insert new records using rs.addNew(使用rs.addNew插入新记录)
Set rs = conn.OpenRecordset("my_dao")
Dim i As Integer
For i = 10 To 15
rs.AddNew
rs!Name = "insert record" & i
rs!Id2 = i
rs.Update
Next i
rs.Close
'rs update..(rs更新)
Set rs = conn.OpenRecordset("my_dao")
rs.Edit
rs!Name = "updated-string"
rs.Update
rs.Close
'fetch the table back...(向后获取表…)
Set rs = conn.OpenRecordset("my_dao", dbOpenDynamic)
str = "Results:"
rs.MoveFirst
While Not rs.EOF
str = " " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print "DATA:" & str
rs.MoveNext
Wend
'rs Scrolling(rs滚动)
rs.MoveFirst
str = " FIRST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
rs.MoveLast
str = " LAST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
rs.MovePrevious
str = " LAST-1 ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
'free all resources(释放所有资源)
rs.Close
queryDef.Close
conn.Close
ws.Close
End Sub
Dim rs As rdoResultset
Dim cn As New rdoConnection
Dim cl As rdoColumn
Dim SQL As String
'cn.Connect = "DSN=test;"
cn.Connect = "DRIVER={MySQL ODBC 3.51 Driver};"_
& "SERVER=localhost;"_
& " DATABASE=test;"_
& "UID=venu;PWD=venu; OPTION=3"
cn.CursorDriver = rdUseOdbc
cn.EstablishConnection rdDriverPrompt
'drop table my_rdo(舍弃表my_rdo)
SQL = "drop table if exists my_rdo"
cn.Execute SQL, rdExecDirect
'create table my_rdo(创建表my_rdo)
SQL = "create table my_rdo(id int, name varchar(20))"
cn.Execute SQL, rdExecDirect
'insert – direct(插入,直接)
SQL = "insert into my_rdo values (100,'venu')"
cn.Execute SQL, rdExecDirect
SQL = "insert into my_rdo values (200,'MySQL')"
cn.Execute SQL, rdExecDirect
'rs insert(rs插入)
SQL = "select * from my_rdo"
Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
rs.AddNew
rs!id = 300
rs!Name = "Insert1"
rs.Update
rs.Close
'rs insert(rs插入)
SQL = "select * from my_rdo"
Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
rs.AddNew
rs!id = 400
rs!Name = "Insert 2"
rs.Update
rs.Close
'rs update(rs更新)
SQL = "select * from my_rdo"
Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
rs.Edit
rs!id = 999
rs!Name = "updated"
rs.Update
rs.Close
'fetch back...
SQL = "select * from my_rdo"
Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
Do Until rs.EOF
For Each cl In rs.rdoColumns
Debug.Print cl.Value,
Next
rs.MoveNext
Debug.Print
Loop
Debug.Print "Row count="; rs.RowCount
'close(关闭)
rs.Close
cn.Close
End Sub
在下面的简单示例中创建了表my_odbc_net,并介绍了它在C#中的使用。
/** * @sample : mycon.cs * @purpose : Demo sample for ODBC.NET using MyODBC * @author : Venu, <> * * (C) Copyright MySQL AB, 1995-2004 * **/ /* build command * * csc /t:exe * /out:mycon.exe mycon.cs * /r:Microsoft.Data.Odbc.dll */ using Console = System.Console; using Microsoft.Data.Odbc; namespace myodbc3 { class mycon { static void Main(string[] args) { try { //Connection string for MyODBC 2.50 /*string MyConString = "DRIVER={MySQL};" + "SERVER=localhost;" + "DATABASE=test;" + "UID=venu;" + "PASSWORD=venu;" + "OPTION=3"; */ //Connection string for MyODBC 3.51 string MyConString = "DRIVER={MySQL ODBC 3.51 Driver};" + "SERVER=localhost;" + "DATABASE=test;" + "UID=venu;" + "PASSWORD=venu;" + "OPTION=3"; //Connect to MySQL using MyODBC OdbcConnection MyConnection = new OdbcConnection(MyConString); MyConnection.Open(); Console.WriteLine("\n !!! success, connected successfully !!!\n"); //Display connection information Console.WriteLine("Connection Information:"); Console.WriteLine("\tConnection String:" + MyConnection.ConnectionString); Console.WriteLine("\tConnection Timeout:" + MyConnection.ConnectionTimeout); Console.WriteLine("\tDatabase:" + MyConnection.Database); Console.WriteLine("\tDataSource:" + MyConnection.DataSource); Console.WriteLine("\tDriver:" + MyConnection.Driver); Console.WriteLine("\tServerVersion:" + MyConnection.ServerVersion); //Create a sample table OdbcCommand MyCommand = new OdbcCommand("DROP TABLE IF EXISTS my_odbc_net",MyConnection); MyCommand.ExecuteNonQuery(); MyCommand.CommandText = "CREATE TABLE my_odbc_net(id int, name varchar(20), idb bigint)"; MyCommand.ExecuteNonQuery(); //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(10,'venu', 300)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());; //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',400)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery()); //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',500)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery()); //Update MyCommand.CommandText = "UPDATE my_odbc_net SET id=999 WHERE id=20"; Console.WriteLine("Update, Total rows affected:" + MyCommand.ExecuteNonQuery()); //COUNT(*) MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_odbc_net"; Console.WriteLine("Total Rows:" + MyCommand.ExecuteScalar()); //Fetch MyCommand.CommandText = "SELECT * FROM my_odbc_net"; OdbcDataReader MyDataReader; MyDataReader = MyCommand.ExecuteReader(); while (MyDataReader.Read()) { if(string.Compare(MyConnection.Driver,"myodbc3.dll") == 0) { Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " + MyDataReader.GetString(1) + " " + MyDataReader.GetInt64(2)); //Supported only by MyODBC 3.51 } else { Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " + MyDataReader.GetString(1) + " " + MyDataReader.GetInt32(2)); //BIGINTs not supported by MyODBC } } //Close all resources MyDataReader.Close(); MyConnection.Close(); } catch (OdbcException MyOdbcException)//Catch any ODBC exception .. { for (int i=0; i < MyOdbcException.Errors.Count; i++) { Console.Write("ERROR #" + i + "\n" + "Message: " + MyOdbcException.Errors[i].Message + "\n" + "Native: " + MyOdbcException.Errors[i].NativeError.ToString() + "\n" + "Source: " + MyOdbcException.Errors[i].Source + "\n" + "SQL: " + MyOdbcException.Errors[i].SQLState + "\n"); } } } } }
在下面的简单示例中创建了表my_vb_net,并介绍了它在VB中的用法。
' @sample : myvb.vb ' @purpose : Demo sample for ODBC.NET using MyODBC ' @author : Venu, <> ' ' (C) Copyright MySQL AB, 1995-2004 ' ' ' ' build command ' ' vbc /target:exe ' /out:myvb.exe ' /r:Microsoft.Data.Odbc.dll ' /r:System.dll ' /r:System.Data.dll ' Imports Microsoft.Data.Odbc Imports System Module myvb Sub Main() Try 'MyODBC 3.51 connection string Dim MyConString As String = "DRIVER={MySQL ODBC 3.51 Driver};" & _ "SERVER=localhost;" & _ "DATABASE=test;" & _ "UID=venu;" & _ "PASSWORD=venu;" & _ "OPTION=3;" 'Connection Dim MyConnection As New OdbcConnection(MyConString) MyConnection.Open() Console.WriteLine ("Connection State::" & MyConnection.State.ToString) 'Drop Console.WriteLine ("Dropping table") Dim MyCommand As New OdbcCommand() MyCommand.Connection = MyConnection MyCommand.CommandText = "DROP TABLE IF EXISTS my_vb_net" MyCommand.ExecuteNonQuery() 'Create Console.WriteLine ("Creating....") MyCommand.CommandText = "CREATE TABLE my_vb_net(id int, name varchar(30))" MyCommand.ExecuteNonQuery() 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(10,'venu')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net(id) VALUES(30)" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Update MyCommand.CommandText = "UPDATE my_vb_net SET id=999 WHERE id=20" Console.WriteLine("Update, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'COUNT(*) MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_vb_net" Console.WriteLine("Total Rows:" & MyCommand.ExecuteScalar()) 'Select Console.WriteLine ("Select * FROM my_vb_net") MyCommand.CommandText = "SELECT * FROM my_vb_net" Dim MyDataReader As OdbcDataReader MyDataReader = MyCommand.ExecuteReader While MyDataReader.Read If MyDataReader("name") Is DBNull.Value Then Console.WriteLine ("id = " & CStr(MyDataReader("id")) & " name = " & _ "NULL") Else Console.WriteLine ("id = " & CStr(MyDataReader("id")) & " name = " & _ CStr(MyDataReader("name"))) End If End While 'Catch ODBC Exception Catch MyOdbcException As OdbcException Dim i As Integer Console.WriteLine (MyOdbcException.ToString) 'Catch program exception Catch MyException As Exception Console.WriteLine (MyException.ToString) End Try End Sub End Module
下面列出了一些MySQL AB公司负责MyODBC和MyODBC 3.51驱动程序开发的人员。
Micheal (Monty) Widenius
Venu Anuganti
Peter Harvey
MySQL Connector/NET包括对下述事宜的完整支持:
· MySQL 5.0特性(存储程序等)。
· MySQL 4.1特性(服务器端的精制语句、Unicode、以及共享内存访问等)。
· 大信息包支持,可发送和接收高达2GB的行和BLOB。
· 协议压缩,允许压缩客户端和服务器之间的数据流。
· 支持使用CP/IP套接字、命名管道、以及Windows共享内存的连接。
· 支持使用CP/IP套接字、或Unix套接字的连接。
· 支持由Novell开发的开放源码Mono框架。
· 可完全管理,不利用MySQL客户端库。
MySQL Connector/NET的开发人员高度尊重用户在软件开发过程中提供的帮助。如果你发现MySQL Connector/NET缺少对你来说很重要的某些特性,或者如果你发现了缺陷,请使用我们的请求该特性或通报问题。
通过上的论坛以及上的邮件列表,可找到针对MySQL Connector/NET的社区支持信息。MySQL AB公司提供付费支持,更多信息请参见。
本文档的目的是作为MySQL Connector/NET的用户指南,而不是语法参考。如果你打算了解详细的语法信息,请阅读MySQL Connector/NET分发版中提供的Documentation.chm文件。
MySQL Connector/NET能够运行在任何支持.NET框架的平台上。.NET框架主要被最近的Microsoft Windows版本支持,通过由Novell开发的Mono框架,在Linux上也支持它(请参见)。
MySQL Connector/NET可通过使用Windows Installer (.msi)安装软件包进行安装,使用该软件包,可在任何Windows操作系统上安装MySQL Connector/NET。MSI软件包包含在名为mysql-connector-net-version.zip的压缩文件中,其中,“version”(版本)指明了MySQL Connector/NET的版本。
可从下述网站下载MySQL Connector/NET:http://dev.mysql.com/downloads/connector/net/1.0.html。
随着Windows XP的发布,Windows Installer(安装器)引擎也予以了更新,对于使用旧版本的用户,可参阅以了解升级至最新版本的更多信息。
要想安装MySQL Connector/NET,请右击MSI文件并选择“安装”。在安装器提示你完成安装参数选择后,安装将自动开始。对于大多数用户,建议采用典型安装。
如果在运行安装器时遇到问题,可下载不带安装器的ZIP文件。该文件名为mysql-connector-net-version-noinstall.zip。使用ZIP程序,将其解压至你所选择的目录。
除非作了其他选择,否则MySQL Connector/NET将被安装到“C:\Program Files\MySQL\MySQL Connector Net X.X.X”,其中,“X.X.X”是你所安装的MySQL Connector/NET的版本号。新安装不会覆盖已有的MySQL Connector/NET版本。
下面介绍了MySQL Connector/NET的主要类:
· MySqlCommand:代表对MySQL数据库进行执行操作的SQL语句。
· MySqlCommandBuilder:自动生成单个表的命令,用于协调对DataSet所作的更改和相关的MySQL数据库。
· MySqlConnection:代表与MySQL服务器数据库的开放式连接。
· MySqlDataAdapter:代表一组数据命令和数据库连接,用于填充数据库和更新MySQL数据库。
· MySqlDataReader:提供了从MySQL数据库读取行的“仅正向”流的一种方式。
· MySqlException:当MySQL返回错误时抛出的异常。
· MySqlHelper:助手类,能使工作变的更简单。
· MySqlTransaction:代表将在MySQL数据库中进行的SQL事务。
在后续段落中,将分别介绍这些对象。这些章节的目的是概要介绍MySQL Connector/NET的主要类,而不是语法参考。如果你打算了解详细的语法信息,请阅读MySQL Connector/NET分发版中提供的Documentation.chm文件。
MySqlCommand类代表对MySQL数据库进行执行操作的SQL语句。
注释:在以前的版本中,采用符号“@”来标识SQL中的参数。它与MySQL用户变量不兼容,因此,现采用符号“?”来定位SQL中的参数。为了支持早期代码,也可以在连接字符串中设置“old syntax=yes”。如果进行了这类设置,请注意,如果无法定义希望在SQL中使用的参数(定义失败),不会给出异常提示。
· CommandText:获取或设置将在数据源上执行的SQL语句。
· CommandTimeout:获取或设置中止执行命令并生成错误之前应等待的时间。
· CommandType:获取或设置值,该值指明了解释CommandText的方式。可能的值包括StoredProcedure、TableDirect和Text。
· Connection:获取或设置该MySqlCommand实例使用的MySqlConnection。
· IsPrepared:如果该命令已准备好,为“真”,否则为“假”。
· Parameters:获取MySqlParameterCollection。
· Transaction:获取或设置MySqlTransaction,MySqlCommand将在其中执行。
· UpdatedRowSource:当DbDataAdapter的Update方法使用它时,用于获取或设置命令结果作用在DataRow上的方式。
· Cancel:尝试取消MySqlCommand的执行。不支持该操作。
· Clone:创建该MySqlCommand对象的克隆对象。包括CommandText、Connection和Transaction属性,以及整个参数列表。
· CreateParameter:创建MySqlParameter对象的新实例。
· Dispose:处理该MySqlCommand实例。
· ExecuteNonQuery:根据连接情况执行SQL语句,并返回受影响的行数。
· ExecuteReader:将CommandText发送给Connection,并创建MySqlDataReader。
· ExecuteScalar:执行查询,并返回查询操作所返回的结果集中第1行的第1列。多余的列或行将被忽略。
· Prepare:在MySQL服务器的1个实例上创建命令的预制版本。
在下例中,介绍了在VB.NET中使用MySqlCommand类的方法:
Public Sub InsertRow(myConnectionString As String) ' If the connection string is null, use a default. If myConnectionString = "" Then myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass" End If Dim myConnection As New MySqlConnection(myConnectionString) Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)" Dim myCommand As New MySqlCommand(myInsertQuery) myCommand.Connection = myConnection myConnection.Open() myCommand.ExecuteNonQuery() myCommand.Connection.Close() End Sub
在下例中,介绍了在C#中使用MySqlCommand类的方法:
public void InsertRow(string myConnectionString) { // If the connection string is null, use a default. if(myConnectionString == "") { myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"; } MySqlConnection myConnection = new MySqlConnection(myConnectionString); string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"; MySqlCommand myCommand = new MySqlCommand(myInsertQuery); myCommand.Connection = myConnection; myConnection.Open(); myCommand.ExecuteNonQuery(); myCommand.Connection.Close(); }
MySqlDataAdapter不会自动生成所需的SQL语句(用于协调对DataSet所作的更改和相关的MySQL实例)。但是,如果设置了MySqlDataAdapter的SelectCommand属性,可以创建MySqlCommandBuilder对象来自动生成针对单个表更新的SQL语句。随后,MySqlCommandBuilder将生成你未设置的任何附加的SQL语句。
一旦你设置了DataAdapter属性,MySqlCommandBuilder会将自己注册为针对OnRowUpdating事件的监听程序。一次只能将1个MySqlDataAdapter或MySqlCommandBuilder对象关联起来。
为了生成INSERT、UPDATE或DELETE语句,MySqlCommandBuilder使用了SelectCommand属性来自动检索所需的元数据集合。如果在检索完元数据后更改了SelectCommand(例如首次更新后),应调用RefreshSchema方法来更新元数据。
SelectCommand也必须返回至少1个主键或唯一列。如果未显示任何返回信息,将生成InvalidOperation异常,而且不会生成命令。
MySqlCommandBuilder还会使用SelectCommand引用的Connection、CommandTimeout和Transaction属性。如果更改了这些属性中的任何1个,或者,如果替换了SelectCommand本身,用户应调用RefreshSchema。如不然,InsertCommand、UpdateCommand和DeleteCommand属性将保持它们以前的值。
如果调用了Dispose,MySqlCommandBuilder将解除与MySqlDataAdapter的关联,已生成的命令将不再使用。
可用属性如下:
· DataAdapter:MySqlCommandBuilder将自己注册为针对RowUpdating事件的监听程序,RowUpdating事件是由在该属性中指定的MySqlDataAdapter生成的。创建了新的MySqlCommandBuilder实例时,将释放任何已有的与MySqlDataAdapter关联的MySqlCommandBuilder。
· QuotePrefix, QuoteSuffix:MySQL中的数据库对象能够包含特殊字符,如空格等,这会使得正常的SQL字符串无法解析。使用QuotePrefix和QuoteSuffix属性,MySqlCommandBuilder能够创建处理该问题的SQL命令。
可用方法如下:
· DeriveParameters:从MySqlCommand指定的存储程序中检索参数信息,并填充所指定MySqlCommand对象的参数集。目前不支持该方法,这是因为MySQL中未提供存储程序。
· GetDeleteCommand:获取用于在数据库上执行删除操作所需的、自动生成的MySqlCommand对象。
· GetInsertCommand:获取用于在数据库上执行插入操作所需的、自动生成的MySqlCommand对象。
· GetUpdateCommand:获取用于在数据库上执行更新操作所需的、自动生成的MySqlCommand对象。
· RefreshSchema:刷新用于生成INSERT、UPDATE或DELETE语句的数据库方案信息。
在下例中,介绍了在VB.NET中使用MySqlCommandBuilder类的方法:
Public Shared Function SelectRows(myConnection As String, mySelectQuery As String, myTableName As String) As DataSet Dim myConn As New MySqlConnection(myConnection) Dim myDataAdapter As New MySqlDataAdapter() myDataAdapter.SelectCommand = New MySqlCommand(mySelectQuery, myConn) Dim cb As SqlCommandBuilder = New MySqlCommandBuilder(myDataAdapter) myConn.Open() Dim ds As DataSet = New DataSet myDataAdapter.Fill(ds, myTableName) ' Code to modify data in DataSet here ' Without the MySqlCommandBuilder this line would fail. myDataAdapter.Update(ds, myTableName) myConn.Close() End Function 'SelectRows
在下例中,介绍了在C#中使用MySqlCommandBuilder类的方法:
public static DataSet SelectRows(string myConnection, string mySelectQuery, string myTableName) { MySqlConnection myConn = new MySqlConnection(myConnection); MySqlDataAdapter myDataAdapter = new MySqlDataAdapter(); myDataAdapter.SelectCommand = new MySqlCommand(mySelectQuery, myConn); MySqlCommandBuilder cb = new MySqlCommandBuilder(myDataAdapter); myConn.Open(); DataSet ds = new DataSet(); myDataAdapter.Fill(ds, myTableName); //code to modify data in DataSet here //Without the MySqlCommandBuilder this line would fail myDataAdapter.Update(ds, myTableName); myConn.Close(); return ds; }
MySqlConnection对象代表与MySQL服务器数据源的会话。创建MySqlConnection实例时,所有属性均将被设置为它们的初始值。关于这些值的列表,请参见MySqlConnection构造函数。
如果MySqlConnection超出范围,不会被关闭。因此,必须通过调用Close或Dispose明确地关闭连接。
· ConnectionString:设置或获取用于连接至MySQL服务器数据库的字符串。
· ConnectionTimeout:获取在中止尝试并生成错误之前为建立连接所需的等待时间。
· Database:获取当前数据库的名称或打开连接后将使用的数据库的名称。
· DataSource:获取将要连接的MySQL服务器的名称。
· ServerThread:返回该连接所使用的服务器线程的ID。
· ServerVersion:获取包含客户端与之相连的MySQL服务器版本的字符串。
· State:获取连接的当前连接的状态。
· UseConnection:与服务器进行通信时,指明该连接是否将使用压缩特性。
· BeginTransaction:开始数据库事务。
· ChangeDatabase:针对打开的MySqlConnection,更改当前数据库。
· Close:关闭与数据库的连接。这是关闭任何打开连接的首选方法。
· CreateCommand:创建并返回与MySqlConnection相关的MySqlCommand对象。
· Dispose:释放MySqlConnection使用的资源。
· Open:用ConnectionString指定的属性设置打开数据库连接。
· Ping:对MySQL服务器执行Ping操作。
在下例中,介绍了在VB.NET中使用MySqlConnection类的方法:
Public Sub InsertRow(myConnectionString As String) ' If the connection string is null, use a default. If myConnectionString = "" Then myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass" End If Dim myConnection As New MySqlConnection(myConnectionString) Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)" Dim myCommand As New MySqlCommand(myInsertQuery) myCommand.Connection = myConnection myConnection.Open() myCommand.ExecuteNonQuery() myCommand.Connection.Close() End Sub
在下例中,介绍了在C#中使用MySqlConnection类的方法:
public void InsertRow(string myConnectionString) { // If the connection string is null, use a default. if(myConnectionString == "") { myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"; } MySqlConnection myConnection = new MySqlConnection(myConnectionString); string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"; MySqlCommand myCommand = new MySqlCommand(myInsertQuery); myCommand.Connection = myConnection; myConnection.Open(); myCommand.ExecuteNonQuery(); myCommand.Connection.Close(); }
当MySQLDataAdapter填充DataSet时,如果表或列不存在,它将为返回的数据创建必要的表和列。但是,在隐式创建的方案中不包括主键信息,除非将MissingSchemaAction属性设为AddWithKey。在使用FillSchema用数据填充它之前,也能让MySQLDataAdapter创建DataSet方案,包含主键信息。
MySQLDataAdapter用于MySqlConnection和MySqlCommand的连接,用以提升连接至MySQL数据库时的性能。
MySQLDataAdapter还包括SelectCommand、InsertCommand、DeleteCommand、UpdateCommand和TableMappings属性,用于简化数据的加载和更新操作。
可用属性如下:
· AcceptChangesDuringFill:获取或设置值,该值指明了在任何填充操作过程中,在将DataRow添加到DataTable后,是否要在DataRow上调用AcceptChanges。
· ContinueUpdateOnError:获取或设置值,该值指定了在行更新过程中出现错误时是否要生成异常项。
· DeleteCommand:获取或设置用于将记录从数据集中删除的SQL语句或存储程序。
· InsertCommand:获取或设置用于在数据集中插入记录的SQL语句或存储程序。
· MissingMappingAction:确定当进入的数据不含匹配表或列时需要采取的动作。
· MissingSchemaAction:确定当已有的DataSet方案与进入数据不匹配时需要采取的动作。
· SelectCommand:获取或设置用于在数据源中选择记录的SQL语句或存储程序。
· TableMappings:获取提供了源表和DataTable之间主映射的集合。
· UpdateCommand:获取或设置用于在数据源中更新记录的SQL语句或存储程序。
· Fill:使用DataSet名称添加或刷新DataSet中的行,以便与数据源中的行匹配,并创建名为“Table”的DataTable。
· FillSchema:将名为“Table”的DataTable添加到指定的DataSet,并配置方案,以便与基于指定SchemaType的数据源中的表匹配。
· GetFillParameters:执行SQL SELECT语句时,按用户获取参数集。
· Update:为指定DataSet中的各插入行、更新行或删除行分别调用INSERT、UPDATE或DELETE语句。
在下例中,介绍了在VB.NET中使用MySqlDataAdapter类的方法:
Public Function SelectRows(dataSet As DataSet, connection As String, query As String) As DataSet Dim conn As New MySqlConnection(connection) Dim adapter As New MySqlDataAdapter() adapter.SelectCommand = new MySqlCommand(query, conn) adapter.Fill(dataset) Return dataset End Function
在下例中,介绍了在C#中使用MySqlDataAdapter类的方法:
public DataSet SelectRows(DataSet dataset,string connection,string query) { MySqlConnection conn = new MySqlConnection(connection); MySqlDataAdapter adapter = new MySqlDataAdapter(); adapter.SelectCommand = new MySqlCommand(query, conn); adapter.Fill(dataset); return dataset; }
要想创建MySQLDataReader,必须调用MySqlCommand对象的ExecuteReader方法,而不是直接使用构造函数。
使用MySqlDataReader的同时,相关的MySqlConnection将忙于MySqlDataReader。除了关闭它之外,不能在MySqlConnection上执行任何操作。该情况将一直持续到调用了MySqlDataReader的“Close”方法为止。
关闭了MySqlDataReader后,你只能调用IsClosed和RecordsAffected属性。尽管在MySqlDataReader存在同时能够访问RecordsAffected属性,但在返回RecordsAffected的值之前总应调用“Close”,以确保准确的返回值。
为了获得最佳性能,MySqlDataReader将避免创建不必要的对象或执行不必要的数据拷贝。其结果是,对诸如GetValue等方法的多个调用会返回对相同对象的引用。如果你准备更改由诸如GetValue等方法返回的对象的基本值,请仔细小心。
· Depth:获取指明当前行嵌套深度的值。目前并不支持方法,总会返回0。
· FieldCount:获取当前行中的列数。
· HasRows:获取值,该值指明了MySqlDataReader是否包含1行或多行。
· IsClosed:获取值,该值指明了和苏剧阅读器是否已关闭。
· Item:以固有格式获取列的值。在C#,该属性是MySqlDataReader类的索引属性。
· RecordsAffected:获取隐执行SQL语句而更改、插入、或删除的行数。
· Close:关闭MySqlDataReader对象。
· GetBoolean:获取指定列的布尔值。
· GetByte:以字节形式获取指定列的值。
· GetBytes:读取从指定列偏移至缓冲的字节流,数组从给定的缓冲偏移位置开始。
· GetChar:以单字符形式获取指定列的值。
· GetChars:读取从指定列偏移至缓冲的字符流,数组从给定的缓冲偏移位置开始。
· GetDataTypeName:获取源数据类型的名称。
· GetDateTime:以DateTime对象形式获取指定列的值。
· GetDecimal:以DateTime对象形式获取指定列的值。
· GetDouble:以双精度浮点数的形式获取指定列的值。
· GetFieldType:获取作为对象数据类型的类型。
· GetFloat:以单精度浮点数的形式获取指定列的值。
· GetGuid:以GUID的形式获取指定列的值。
· GetInt16:以16位带符号整数的形式获取指定列的值。
· GetInt32:以32位带符号整数的形式获取指定列的值。
· GetInt64:以64位带符号整数的形式获取指定列的值。
· GetMySqlDateTime:以MySqlDateTime对象的形式获取指定列的值。
· GetName:获取指定列的名称。
· GetOrdinal:给定列名,获取列的顺序。
· GetSchemaTable:返回描述了MySqlDataReader的列元数据的DataTable。
· GetString:以String对象的形式获取指定列的值。
· GetTimeSpan:以TimeSpan对象的形式获取指定列的值。
· GetUInt16:以16位无符号整数的形式获取指定列的值。
· GetUInt32:以32位无符号整数的形式获取指定列的值。
· GetUInt64:以64位无符号整数的形式获取指定列的值。
· GetValue:以固有格式获取指定列的值。
· GetValues:获取当前行集合中的所有属性列。
· IsDBNull:获取值,该值指明了列中是否包含不存在或丢失的值。
· NextResult:读取批SQL语句的结果时,使数据阅读器跳到下一个结果。
· Read:使MySqlDataReader跳到下一条记录。
在下例中,介绍了在VB.NET中使用MySqlDataReader类的方法:
Public Sub ReadMyData(myConnString As String) Dim mySelectQuery As String = "SELECT OrderID, CustomerID FROM Orders" Dim myConnection As New MySqlConnection(myConnString) Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) myConnection.Open() Dim myReader As MySqlDataReader myReader = myCommand.ExecuteReader() ' Always call Read before accessing data. While myReader.Read() Console.WriteLine((myReader.GetInt32(0) & ", " & myReader.GetString(1))) End While ' always call Close when done reading. myReader.Close() ' Close the connection when done with it. myConnection.Close() End Sub 'ReadMyData
在下例中,介绍了在C#中使用MySqlDataReader类的方法:
public void ReadMyData(string myConnString) { string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders"; MySqlConnection myConnection = new MySqlConnection(myConnString); MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection); myConnection.Open(); MySqlDataReader myReader; myReader = myCommand.ExecuteReader(); // Always call Read before accessing data. while (myReader.Read()) { Console.WriteLine(myReader.GetInt32(0) + ", " + myReader.GetString(1)); } // always call Close when done reading. myReader.Close(); // Close the connection when done with it. myConnection.Close(); }
抛出异常时,打开的连接不会自动关闭。如果客户端应用程序判定该异常是致命的,应关闭任何打开的MySqlDataReader对象或MySqlConnection对象。
· HelpLink:获取或设置指向与该异常相关的帮助文件的链接。
· InnerException:获取导致当前异常的异常实例。
· IsFatal:如果该异常是致命的,为“真”,并关闭连接,如果不是致命的,为“假”。
· Message:获取描述当前异常的消息。
· Number:获取指明错误类型的编号。
· Source:获取或设置导致错误的应用程序或对象的名称。
· StackTrace:获取抛出当前异常时在调用堆栈上帧的字符串表征。
· TargetSite:获取抛出当前异常的方法。
该示例介绍在VB.NET下使用MySqlException类的方法。
Public Sub ShowException() Dim mySelectQuery As String = "SELECT column1 FROM table1" Dim myConnection As New MySqlConnection ("Data Source=localhost;Database=Sample;") Dim myCommand As New MySqlCommand(mySelectQuery, myConnection) Try myCommand.Connection.Open() Catch e As MySqlException MessageBox.Show( e.Message ) End Try End Sub
该示例介绍在C#下使用MySqlException类的方法。
public void ShowException() { string mySelectQuery = "SELECT column1 FROM table1"; MySqlConnection myConnection = new MySqlConnection("Data Source=localhost;Database=Sample;"); MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection); try { myCommand.Connection.Open(); } catch (MySqlException e) { MessageBox.Show( e.Message ); } }
· ExecuteDataRow:执行单个SQL语句并返回结果集的第1行。在该方法的执行过程中,将创建、打开并关闭1个新的MySqlConnection对象。
· ExecuteDataset:执行单个SQL命令并返回DataSet中的结果集。在该方法的执行过程中,将创建、打开并关闭1个新的MySqlConnection对象。
· ExecuteNonQuery:在MySQL数据库上执行单个命令。调用该方法时,将认为MySqlConnection已打开,方法执行完后,MySqlConnection仍保持打开状态。
· ExecuteReader:Overloaded:在MySQL数据库上执行单个命令。
· ExecuteScalar:在MySQL数据库上执行单个命令。
· UpdateDataSet:用来自给定DataSet的数据更新给定表。
· Connection:获取与事务相关的MySqlConnection对象,如果事务不再有效,获取空引用(在Visual Basic中为Nothing)。
· IsolationLevel:为该事务指定IsolationLevel。
· Commit:提交数据库事务。
· Rollback:从挂起状态回滚事务。
在下例中,介绍了在VB.NET中使用MySqlTransaction类的方法:
Public Sub RunTransaction(myConnString As String) Dim myConnection As New MySqlConnection(myConnString) myConnection.Open() Dim myCommand As MySqlCommand = myConnection.CreateCommand() Dim myTrans As MySqlTransaction ' Start a local transaction myTrans = myConnection.BeginTransaction() ' Must assign both transaction object and connection ' to Command object for a pending local transaction myCommand.Connection = myConnection myCommand.Transaction = myTrans Try myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')" myCommand.ExecuteNonQuery() myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')" myCommand.ExecuteNonQuery() myTrans.Commit() Console.WriteLine("Both records are written to database.") Catch e As Exception Try myTrans.Rollback() Catch ex As MySqlException If Not myTrans.Connection Is Nothing Then Console.WriteLine("An exception of type " & ex.GetType().ToString() & _ " was encountered while attempting to roll back the transaction.") End If End Try Console.WriteLine("An exception of type " & e.GetType().ToString() & _ "was encountered while inserting the data.") Console.WriteLine("Neither record was written to database.") Finally myConnection.Close() End Try End Sub 'RunTransaction
在下例中,介绍了在C#中使用MySqlTransaction类的方法:
public void RunTransaction(string myConnString) { MySqlConnection myConnection = new MySqlConnection(myConnString); myConnection.Open(); MySqlCommand myCommand = myConnection.CreateCommand(); MySqlTransaction myTrans; // Start a local transaction myTrans = myConnection.BeginTransaction(); // Must assign both transaction object and connection // to Command object for a pending local transaction myCommand.Connection = myConnection; myCommand.Transaction = myTrans; try { myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')"; myCommand.ExecuteNonQuery(); myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')"; myCommand.ExecuteNonQuery(); myTrans.Commit(); Console.WriteLine("Both records are written to database."); } catch(Exception e) { try { myTrans.Rollback(); } catch (MySqlException ex) { if (myTrans.Connection != null) { Console.WriteLine("An exception of type " + ex.GetType() + " was encountered while attempting to roll back the transaction."); } } Console.WriteLine("An exception of type " + e.GetType() + " was encountered while inserting the data."); Console.WriteLine("Neither record was written to database."); } finally { myConnection.Close(); } }
即使在使用MySqlHelper类时,MySqlConnection对象也会被Helper类创建。
在本节中,介绍了使用MySqlConnection对象连接到MySQL的方法。
MySqlConnection对象是使用连接字符串配置的。1个连接字符串包含服务器键/值对,由分号隔开。每个键/值对由等号连接。
下面给出了1个简单的连接字符串示例:
Server=127.0.0.1;Uid=root;Pwd=12345;Database=test;
在本例中,对MySqlConnection对象进行了配置,使用用户名“root”和密码“12345”与位于127.0.0.1的MySQL服务器相连。所有语句的默认数据库为测试数据库。
典型的选项如下(关于选项的完整清单,请参见API文档):
· Server:将要连接的MySQL实例的名称或网络地址。默认为本地主机。别名包括Host, Data Source, DataSource, Address, Addr和Network Address。
· Uid:连接时使用的MySQL用户账户。别名包括User Id, Username和User name。
· Pwd:MySQL账户的密码。也可以使用别名密码。
· Database:所有语句作用于的默认数据库。默认为mysql。也可以使用别名Initial Catalog。
· Port:MySQL用于监听连接的端口。默认为3306。将该值指定为“-1”将使用命名管道连接。
一旦创建了连接字符串,可使用它打开与MySQL服务器的连接。
下述代码用于创建MySqlConnection对象,指定连接字符串,并打开连接。
[VB]
Dim conn As New MySql.Data.MySqlClient.MySqlConnection Dim myConnectionString as String myConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test;" Try conn.ConnectionString = myConnectionString conn.Open() Catch ex As MySql.Data.MySqlClient.MySqlException MessageBox.Show(ex.Message) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; string myConnectionString; myConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { conn = new MySql.Data.MySqlClient.MySqlConnection(); conn.ConnectionString = myConnectionString; conn.Open(); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show(ex.Message); }
你也可以将连接字符串传递给MySqlConnection类的构造函数:
[VB]
Dim myConnectionString as String myConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test;" Try Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString) conn.Open() Catch ex As MySql.Data.MySqlClient.MySqlException MessageBox.Show(ex.Message) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; string myConnectionString; myConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString); conn.Open(); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show(ex.Message); }
由于与外部服务器的连接不可预测,应为你的.NET应用程序添加错误处理功能,这点很重要。出现连接错误时,MySqlConnection类将返回1个MySqlException对象。该对象有两个在处理错误时十分有用的属性:
· Message:描述当前异常的消息。
· Number:MySQL错误编号。
处理错误时,可根据错误编号了解应用程序的响应。进行连接时最常见的两个错误编号如下:
· 0: 无法连接到服务器。
· 1045: 无效的用户名和/或密码。
在下面的代码中,介绍了根据实际错误改编应用程序的方法:
[VB]
Dim myConnectionString as String myConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test;" Try Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString) conn.Open() Catch ex As MySql.Data.MySqlClient.MySqlException Select Case ex.Number Case 0 MessageBox.Show("Cannot connect to server. Contact administrator") Case 1045 MessageBox.Show("Invalid username/password, please try again") End Select End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; string myConnectionString; myConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString); conn.Open(); } catch (MySql.Data.MySqlClient.MySqlException ex) { switch (ex.Number) { case 0: MessageBox.Show("Cannot connect to server. Contact administrator"); case 1045: MessageBox.Show("Invalid username/password, please try again"); } }
对于多次执行的语句,预处理执行的速度快于直接执行,这是因为只需进行1次解析操作。在直接执行的情况下,每次执行时均将进行解析操作。预处理执行还能降低网络通信量,这是因为对于预处理语句的每次执行,仅需发送用于参数的数据。
预处理语句的另一优点是,它能使用二进制协议,这使得客户端和服务器间的数据传输更有效率。
输入语句后,调用MySqlCommand对象的.Prepare方法。完成语句的准备后,为查询中的每个元素添加参数。
输入查询并输入参数后,使用.ExecuteNonQuery()、.ExecuteScalar()、或.ExecuteReader方法执行语句。
对于后续的执行操作,仅需更改参数值并再次调用执行方法,无需设置.CommandText属性或重新定义参数。
[VB]
Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
conn.ConnectionString = strConnection
Try
conn.Open()
cmd.Connection = conn
cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)"
cmd.Prepare()
cmd.Parameters.Add("?number", 1)
cmd.Parameters.Add("?text", "One")
For i = 1 To 1000
cmd.Parameters("?number").Value = i
cmd.Parameters("?text").Value = "A string value"
cmd.ExecuteNonQuery()
Next
Catch ex As MySqlException
MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();
conn.ConnectionString = strConnection;
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)";
cmd.Prepare();
cmd.Parameters.Add("?number", 1);
cmd.Parameters.Add("?text", "One");
for (int i=1; i <= 1000; i++)
{
cmd.Parameters["?number"].Value = i;
cmd.Parameters["?text"].Value = "A string value";
cmd.ExecuteNonQuery();
}
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
随着MySQL版本5的发布,MySQL服务器目前支持存储程序,它采用了SQL 2003存储程序的语法。
存储程序指的是能够保存在服务器上的一组SQL语句。 一旦完成了该操作,客户端无需再次发出单独语句,而仅需引用存储程序取而代之。
在下述情况下,存储程序尤其有用:
· 多个客户端应用程序是采用不同语言编写的或工作在不同平台上,但需执行相同的数据库操作。
· 安全性极其重要时。例如,对于所有共同操作,银行采用了存储程序。这样,就能提供一致且安全的环境,而且这类存储程序能够保证每次操作均具有恰当登录。在这类设置下,应用程序和用户无法直接访问数据库表,但能执行特定的存储程序。
MySQL Connector/NET支持通过MySqlCommand对象的存储程序调用。使用MySqlCommand.Parameters集,能够将数据传入和传出MySQL存储程序。
在本节中,未深度介绍创建存储程序方面的信息,要想了解这类信息,请参见MySQL参考手册的存储程序。
在MySQL Connector/NET安装的Samples目录下,可找到1个相应的示例,该示例演示了与MySQL Connector/NET一起使用存储程序的方法。
可使用多种工具创建MySQL中的存储程序。首先,可使用mysql命令行客户端创建存储程序。其次,可使用MySQL Query Browser GUI客户端创建存储程序。最后,可使用MySqlCommand对象的.ExecuteNonQuery方法创建存储程序。
[VB]
Dim conn As New MySqlConnection Dim cmd As New MySqlCommand conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test" Try conn.Open() cmd.Connection = conn cmd.CommandText = "CREATE PROCEDURE add_emp(" _ & "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " _ & "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " _ & "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END" cmd.ExecuteNonQuery() Catch ex As MySqlException MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { conn.Open(); cmd.Connection = conn; cmd.CommandText = "CREATE PROCEDURE add_emp(" + "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " + "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " + "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END"; cmd.ExecuteNonQuery(); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
要想使用MySQL Connector/NET来调用存储程序,应创建1个MySqlCommand对象,并将存储程序名作为.CommandText属性传递。将.CommandType属性设置为CommandType.StoredProcedure。
命名了存储程序后,为存储程序中的每个参数创建1个MySqlCommand参数。用参数名和包含值的对象定义IN参数,用参数名和预计将返回的数据类型定义OUT参数。对于所有参数,均需定义参数方向。
定义完参数后,使用MySqlCommand.ExecuteNonQuery()方法调用存储程序。
[VB]
Dim conn As New MySqlConnection Dim cmd As New MySqlCommand conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test" Try conn.Open() cmd.Connection = conn cmd.CommandText = "add_emp" cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add("?lname", 'Jones') cmd.Parameters("?lname").Direction = ParameterDirection.Input cmd.Parameters.Add("?fname", 'Tom') cmd.Parameters("?fname").Direction = ParameterDirection.Input cmd.Parameters.Add("?bday", #12/13/1977 2:17:36 PM#) cmd.Parameters("?bday").Direction = ParameterDirection.Input cmd.Parameters.Add("?empno", MySqlDbType.Int32) cmd.Parameters("?empno").Direction = ParameterDirection.Output cmd.ExecuteNonQuery() MessageBox.Show(cmd.Parameters("?empno").Value) Catch ex As MySqlException MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { conn.Open(); cmd.Connection = conn; cmd.CommandText = "add_emp"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("?lname", "Jones"); cmd.Parameters("?lname").Direction = ParameterDirection.Input; cmd.Parameters.Add("?fname", "Tom"); cmd.Parameters("?fname").Direction = ParameterDirection.Input; cmd.Parameters.Add("?bday", DateTime.Parse("12/13/1977 2:17:36 PM")); cmd.Parameters("?bday").Direction = ParameterDirection.Input; cmd.Parameters.Add("?empno", MySqlDbType.Int32); cmd.Parameters("?empno").Direction = ParameterDirection.Output; cmd.ExecuteNonQuery(); MessageBox.Show(cmd.Parameters("?empno").Value); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
可使用Connector/NET访问保存在BLOB列中的数据,并能使用客户端代码对这类数据进行操作。使用Connector/NET和BLOB数据时,无特殊要求。
在本节中,给出了数个简单的代码示例,在MySQL Connector/NET安装的Samples目录下,可找到1个完整的示例应用程序。
CREATE TABLE file(
file_id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
file_name VARCHAR(64) NOT NULL,
file_size MEDIUMINT UNSIGNED NOT NULL,
file MEDIUMBLOB NOT NULL);
完成表的创建后,或许需要更改max_allowed_packet系统变量。该变量决定了能够发送给MySQL服务器的信息包(即单个行)大小。默认情况下,服务器能够接受来自客户端应用程序的信息包最大为1MB。如果不打算超过1MB,情况良好。如果打算在文件传输中超出1MB,必须增加该数值。
可以使用“MySQL系统管理员的启动变量”屏幕更改max_allowed_packet选项。在“联网”选项卡的“内存”部分,恰当调整“允许的最大值”选项。完成值的调整后,点击“应用更改”按钮,并使用“MySQL管理员”的“服务控制”屏幕重新启动服务器。也可以在my.cnf文件中直接调整该值(添加1行,max_allowed_packet=xxM),或在MySQL中使用SET max_allowed_packet=xxM。
设置max_allowed_packet时应保守些,这是因为传输BLOB数据需要一段时间。恰当地设置该值,使之与预期使用相符,并在必要时增大该值。
要想将文件写入数据库,需要将文件转换为字节数组,然后将字节数组用作INSERT查询的参数。
在下述代码中,使用FileStream对象打开了1个文件,将其读入至字节数组,然后将其插入到文件表中:
[VB]
Dim conn As New MySqlConnection Dim cmd As New MySqlCommand Dim SQL As String Dim FileSize As UInt32 Dim rawData() As Byte Dim fs As FileStream conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test" Try fs = New FileStream("c:\image.png", FileMode.Open, FileAccess.Read) FileSize = fs.Length rawData = New Byte(FileSize) {} fs.Read(rawData, 0, FileSize) fs.Close() conn.Open() SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)" cmd.Connection = conn cmd.CommandText = SQL cmd.Parameters.Add("?FileName", strFileName) cmd.Parameters.Add("?FileSize", FileSize) cmd.Parameters.Add("?File", rawData) cmd.ExecuteNonQuery() MessageBox.Show("File Inserted into database successfully!", _ "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk) conn.Close() Catch ex As Exception MessageBox.Show("There was an error: " & ex.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); string SQL; UInt32 FileSize; byte[] rawData; FileStream fs; conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { fs = new FileStream(@"c:\image.png", FileMode.Open, FileAccess.Read); FileSize = fs.Length; rawData = new byte[FileSize]; fs.Read(rawData, 0, FileSize); fs.Close(); conn.Open(); SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)"; cmd.Connection = conn; cmd.CommandText = SQL; cmd.Parameters.Add("?FileName", strFileName); cmd.Parameters.Add("?FileSize", FileSize); cmd.Parameters.Add("?File", rawData); cmd.ExecuteNonQuery(); MessageBox.Show("File Inserted into database successfully!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); conn.Close(); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
将字节数组指定为MySqlCommand对象的参数后,调用ExecuteNonQuery方法,并将BLOB插入到文件表中。
一旦将文件加载到了文件表中,就能使用MySqlDataReader类来检索它。
在下述代码中,从文件表提取了1行,然后将数据装载到要写入至磁盘的FileStream对象。
[VB]
Dim conn As New MySqlConnection Dim cmd As New MySqlCommand Dim myData As MySqlDataReader Dim SQL As String Dim rawData() As Byte Dim FileSize As UInt32 Dim fs As FileStream conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test" SQL = "SELECT file_name, file_size, file FROM file" Try conn.Open() cmd.Connection = conn cmd.CommandText = SQL myData = cmd.ExecuteReader If Not myData.HasRows Then Throw New Exception("There are no BLOBs to save") myData.Read() FileSize = myData.GetUInt32(myData.GetOrdinal("file_size")) rawData = New Byte(FileSize) {} myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize) fs = New FileStream("C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write) fs.Write(rawData, 0, FileSize) fs.Close() MessageBox.Show("File successfully written to disk!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk) myData.Close() conn.Close() Catch ex As Exception MessageBox.Show("There was an error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; MySql.Data.MySqlClient.MySqlDataReader myData; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); string SQL; UInt32 FileSize; byte[] rawData; FileStream fs; conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; SQL = "SELECT file_name, file_size, file FROM file"; try { conn.Open(); cmd.Connection = conn; cmd.CommandText = SQL; myData = cmd.ExecuteReader(); if (! myData.HasRows) throw new Exception("There are no BLOBs to save"); myData.Read(); FileSize = myData.GetUInt32(myData.GetOrdinal("file_size")); rawData = new byte[FileSize]; myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize); fs = new FileStream(@"C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write); fs.Write(rawData, 0, FileSize); fs.Close(); MessageBox.Show("File successfully written to disk!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); myData.Close(); conn.Close(); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
MySqlDataReader的GetOrdinal方法可用于确定命名列的整数索引。如果SELECT查询的列顺序发生变化,使用GetOrdinal方法能够防止错误。
在MySQL Connector/NET安装的Samples目录的CrystalDemo子目录下,可找到完整的示例应用程序。
在Crystal Reports中创建报告时,在设计报告时,有两个用于访问MySQL数据的选项。
第1个选项是,设计报告时,使用Connector/ODBC作为ADO数据源。你能够浏览数据库,并使用拖放式操作选择表和字段以创建报告。该方法的缺点是,必须在应用程序中执行额外操作以生成与报告预期的数据集匹配的数据集。
第2个选项是在VB.NET中创建数据集,并将其保存为XML格式。随后,该XML文件可被用于设计报告。在应用程序中显示报告时,它的表现相当良好,但设计时的通用性较差,这是因为在创建数据集时,必须选择所有的相关列。如果忘记选择了某一列,在能够将列添加到报告前,必须重新创建数据集。
使用下述代码,可根据查询操作创建数据集,并将其写入磁盘。
[VB]
Dim myData As New DataSet Dim conn As New MySqlConnection Dim cmd As New MySqlCommand Dim myAdapter As New MySqlDataAdapter conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=world" Try conn.Open() cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _ & "country.name, country.population, country.continent " _ & "FROM country, city ORDER BY country.continent, country.name" cmd.Connection = conn myAdapter.SelectCommand = cmd myAdapter.Fill(myData) myData.WriteXml("C:\dataset.xml", XmlWriteMode.WriteSchema) Catch ex As Exception MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
DataSet myData = new DataSet(); MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; MySql.Data.MySqlClient.MySqlDataAdapter myAdapter; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter(); conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " + "country.name, country.population, country.continent " + "FROM country, city ORDER BY country.continent, country.name"; cmd.Connection = conn; myAdapter.SelectCommand = cmd; myAdapter.Fill(myData); myData.WriteXml(@"C:\dataset.xml", XmlWriteMode.WriteSchema); } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error); }
如果你选择使用Connector/ODBC来设计报告,可从dev.mysql.com下载它。
向导首先要求你提供数据源。如果你正使用Connector/ODBC作为数据源,选择数据源时,请使用OLE DB (ADO)树的“用于ODBC的OLEDB provider”选项,,而不是来自ODBC (RDO)的对应选项。如果你使用的是已保存的数据集,请选择ADO.NET (XML)选项,并浏览你保存的数据集。
在报告的创建过程中,剩余部分将由向导自动完成。
创建完报告后,选择“文件”菜单中的“Report Options...”菜单项。取消对“Save Data With Report”(与报告一起保存数据)选项的选择。这样,就能防止保存的数据干扰应用程序中的数据加载操作。
要想显示报告,首先用报告所需的数据填充数据集,然后加载报告,并将其与绑定到数据集。最后,将报告传递给crViewer控制,以便向用户显示它。
在显示报告的项目中,需要下述引用:
· CrytalDecisions.CrystalReports.Engine
· CrystalDecisions.ReportSource
· CrystalDecisions.Shared
· CrystalDecisions.Windows.Forms
在下述代码中,假定你使用数据集(用创建数据源中给出的代码保存的数据集)创建了报告,并在名为“myViewer”的表单上有1个crViewer控件。
[VB]
Imports CrystalDecisions.CrystalReports.Engine Imports System.Data Imports MySql.Data.MySqlClient Dim myReport As New ReportDocument Dim myData As New DataSet Dim conn As New MySqlConnection Dim cmd As New MySqlCommand Dim myAdapter As New MySqlDataAdapter conn.ConnectionString = _ "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=test" Try conn.Open() cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _ & "country.name, country.population, country.continent " _ & "FROM country, city ORDER BY country.continent, country.name" cmd.Connection = conn myAdapter.SelectCommand = cmd myAdapter.Fill(myData) myReport.Load(".\world_report.rpt") myReport.SetDataSource(myData) myViewer.ReportSource = myReport Catch ex As Exception MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
using CrystalDecisions.CrystalReports.Engine; using System.Data; using MySql.Data.MySqlClient; ReportDocument myReport = new ReportDocument(); DataSet myData = new DataSet(); MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; MySql.Data.MySqlClient.MySqlDataAdapter myAdapter; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter(); conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " + "country.name, country.population, country.continent " + "FROM country, city ORDER BY country.continent, country.name"; cmd.Connection = conn; myAdapter.SelectCommand = cmd; myAdapter.Fill(myData); myReport.Load(@".\world_report.rpt"); myReport.SetDataSource(myData); myViewer.ReportSource = myReport; } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error); }
使用相同的查询(用于生成前面保存的数据集),可生成新的数据集。一旦填充了数据集,可使用ReportDocument加载报告文件,并将其与数据集绑定在一起。ReportDocument是作为crViewer的ReportSource而传递的。
使用Connector/ODBC从单个表创建报告时,采用了相同的方法。数据集替换报告中使用的表,并恰当显示报告。
如果报告是使用Connector/ODBC从多个表创建的,在我们的应用程序中必须创建具有多个表的数据集。这样,就能用数据集中的报告替换报告数据源中的各个表。
在我们的MySqlCommand对象中提供多条SELECT语句,通过该方式,用多个表填充数据集。这些SELECT语句基于SQL查询,如数据库菜单“Show SQL Query”选项中的“Crystal Reports”中显示的那样。假定有下述查询:
SELECT `country`.`Name`, `country`.`Continent`, `country`.`Population`, `city`.`Name`, `city`.`Population`
FROM `world`.`country` `country` LEFT OUTER JOIN `world`.`city` `city` ON `country`.`Code`=`city`.`CountryCode`
ORDER BY `country`.`Continent`, `country`.`Name`, `city`.`Name`
该查询将被转换为两条SELECT查询,并以下述代码显示:
[VB]
Imports CrystalDecisions.CrystalReports.Engine Imports System.Data Imports MySql.Data.MySqlClient Dim myReport As New ReportDocument Dim myData As New DataSet Dim conn As New MySqlConnection Dim cmd As New MySqlCommand Dim myAdapter As New MySqlDataAdapter conn.ConnectionString = "server=127.0.0.1;" _ & "uid=root;" _ & "pwd=12345;" _ & "database=world" Try conn.Open() cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER BY countrycode, name; " _ & "SELECT name, population, code, continent FROM country ORDER BY continent, name" cmd.Connection = conn myAdapter.SelectCommand = cmd myAdapter.Fill(myData) myReport.Load(".\world_report.rpt") myReport.Database.Tables(0).SetDataSource(myData.Tables(0)) myReport.Database.Tables(1).SetDataSource(myData.Tables(1)) myViewer.ReportSource = myReport Catch ex As Exception MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
[C#]
using CrystalDecisions.CrystalReports.Engine; using System.Data; using MySql.Data.MySqlClient; ReportDocument myReport = new ReportDocument(); DataSet myData = new DataSet(); MySql.Data.MySqlClient.MySqlConnection conn; MySql.Data.MySqlClient.MySqlCommand cmd; MySql.Data.MySqlClient.MySqlDataAdapter myAdapter; conn = new MySql.Data.MySqlClient.MySqlConnection(); cmd = new MySql.Data.MySqlClient.MySqlCommand(); myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter(); conn.ConnectionString = "server=127.0.0.1;uid=root;" + "pwd=12345;database=test;"; try { cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER " + "BY countrycode, name; SELECT name, population, code, continent FROM " + "country ORDER BY continent, name"; cmd.Connection = conn; myAdapter.SelectCommand = cmd; myAdapter.Fill(myData); myReport.Load(@".\world_report.rpt"); myReport.Database.Tables(0).SetDataSource(myData.Tables(0)); myReport.Database.Tables(1).SetDataSource(myData.Tables(1)); myViewer.ReportSource = myReport; } catch (MySql.Data.MySqlClient.MySqlException ex) { MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error); }
该方法会导致性能问题,这是因为Crystal Reports必须在客户端一侧将表绑定在一起,与使用以前保存的数据集相比,速度较慢。
在本节中,介绍了使用MySQL Connector/NET时恰当处理日期和时间信息的方法。
由于该原因,不能用MySqlDataAdapter类的Fill方法填充.NET DataSet对象,这是因为无效日期会导致System.ArgumentOutOfRangeException异常。
在客户端上限制无效日期十分简单,即总使用.NET DateTime类来处理日期。DateTime类仅允许有效日期,从而确保了数据库中的值也是有效的。该方法的缺点是,在使用.NET和非.NET代码操作数据库的混合环境下不能使用它,这是因为各应用程序必须执行自己的日期验证。
MySQL 5.0.2和更高版本的用户可使用新的传统SQL模式来限制无效日期值。关于使用传统SQL模式的更多信息,请参见http://dev.mysql.com/doc/mysql/en/server-sql-mode.html。
MySqlDateTime数据类型支持MySQL服务器支持的相同日期值。MySQL Connector/NET的默认行为是,对有效的日期值返回1个.NET DateTime对象,对无效日期值返回错误。可以更改该默认方式,使MySQL Connector/NET为无效日期返回MySqlDateTime对象。
要想使MySQL Connector/NET为无效日期返回MySqlDateTime对象,可在连接字符串中添加下行:
Allow Zero Datetime=True
请注意,使用MySqlDateTime类仍会产生问题。下面介绍了一些已知问题:
1. 无效日期的数据绑定仍会导致错误(零日期0000-00-00看上去不存在该问题)。
2. ToString方法返回按标准MySQL格式进行格式处理的日期(例如,2005-02-23 08:50:25)。这与.NET DateTime类的ToString行为不同。
3. MySqlDateTime类支持NULL日期,但.NET DateTime类不支持NULL日期。如果未首先检查NULL,在试图将MySQLDateTime转换为DateTime时,会导致错误。
由于存在上述已知事宜,最佳建议仍是,在你的应用程序中仅使用有效日期。
.NET DateTime数据类型不能处理NULL值。同样,在查询中为DateTime变量赋值时,必须首先检查值是否是NULL。
使用MySqlDataReader时,在赋值前,应使用.IsDBNull方法检查值是否为NULL:
[VB]
If Not myReader.IsDBNull(myReader.GetOrdinal("mytime")) Then myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime")) Else myTime = DateTime.MinValue End If
[C#]
if (! myReader.IsDBNull(myReader.GetOrdinal("mytime"))) myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime")); else myTime = DateTime.MinValue;