Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103728604
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Mysql/postgreSQL

2008-05-12 15:15:10

26.1.16. MyODBC API引用

在本节中,概要介绍了按功能分类的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

释放连接句柄。

26.1.17. MyODBC数据类型

在下表中,介绍了驱动程序将服务器数据类型映射为默认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

26.1.18. MyODBC错误代码

在下表中,列出了驱动程序返回的除服务器错误之外的错误代码列表:

本机代码

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

通信链接失败。

26.1.19. MyODBC与VB:ADO、DAO和RDO

在本节中,给出了MySQL ODBC 3.51驱动程序与ADO、DAO和RDO一起使用的一些简单示例。

26.1.19.1. ADO: rs.addNew, rs.delete和rs.update

在下面的ADO(ActiveX数据对象)示例中,创建了表my_ado,并演示了rs.addNewrs.deleters.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 insertrs插入)
rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
rs.AddNew
rs!Name = "Monty"
rs!txt = "Insert row"
rs.Update
rs.Close
 
'rs updaters更新)
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 deleters删除)
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

26.1.19.2. DAO: rs.addNew, rs.update和滚动

在下面的DAO(数据访问对象)示例中,创建了表my_dao,并演示了rs.addNewrs.update、以及结果集滚动的用法。
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 Scrollingrs滚动)
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

26.1.19.3. RDO: rs.addNew和rs.update

在下面的RDO(远程数据对象)示例中,创建了表my_rdo,并演示了rs.addNewrs.update的用法。
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 insertrs插入)
  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 insertrs插入)
  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 updaters更新)
  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

26.1.20. MyODBC与Microsoft.NET

本节包含一些简单示例,介绍了MyODBC驱动程序与ODBC.NET一起使用的用法。

26.1.20.1. ODBC.NET: CSHARP(C#)

在下面的简单示例中创建了表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");
      }
    }
  }
}
}

26.1.20.2. ODBC.NET: VB

在下面的简单示例中创建了表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

26.1.21. 感谢

下面列出了一些MySQL AB公司负责MyODBC和MyODBC 3.51驱动程序开发的人员。

  • Micheal (Monty) Widenius

  • Venu Anuganti

  • Peter Harvey

26.2. MySQL Connector/NET

26.2.1. 前言

使用MySQL Connector/NET,开发人员能够方便地创建需要安全和高性能数据连接(与MySQL)的.NET应用程序。它实施了所需的ADO.NET接口,并将其集成到了ADO.NET aware工具中。开发人员能够使用他们选择的.NET语言创建应用程序。MySQL Connector/NET是用100%纯C#语言编写的可完全管理的ADO.NET驱动程序。

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文件。

26.2.2. 下载并安装MySQL Connector/NET

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版本。

26.2.3. 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文件。

26.2.3.1. MySqlCommand类

MySqlCommand类代表对MySQL数据库进行执行操作的SQL语句。

注释:在以前的版本中,采用符号“@”来标识SQL中的参数。它与MySQL用户变量不兼容,因此,现采用符号“?”来定位SQL中的参数。为了支持早期代码,也可以在连接字符串中设置“old syntax=yes”。如果进行了这类设置,请注意,如果无法定义希望在SQL中使用的参数(定义失败),不会给出异常提示。

26.2.3.1.1. 属性
可用属性如下:

·         CommandText:获取或设置将在数据源上执行的SQL语句。

·         CommandTimeout:获取或设置中止执行命令并生成错误之前应等待的时间。

·         CommandType:获取或设置值,该值指明了解释CommandText的方式。可能的值包括StoredProcedureTableDirectText

·         Connection:获取或设置该MySqlCommand实例使用的MySqlConnection。

·         IsPrepared:如果该命令已准备好,为“真”,否则为“假”。

·         Parameters:获取MySqlParameterCollection。

·         Transaction:获取或设置MySqlTransaction,MySqlCommand将在其中执行。

·         UpdatedRowSource:当DbDataAdapter的Update方法使用它时,用于获取或设置命令结果作用在DataRow上的方式。

26.2.3.1.2. 方法
可用方法如下:

·         Cancel:尝试取消MySqlCommand的执行。不支持该操作。

·         Clone:创建该MySqlCommand对象的克隆对象。包括CommandText、Connection和Transaction属性,以及整个参数列表。

·         CreateParameter:创建MySqlParameter对象的新实例。

·         Dispose:处理该MySqlCommand实例。

·         ExecuteNonQuery:根据连接情况执行SQL语句,并返回受影响的行数。

·         ExecuteReader:将CommandText发送给Connection,并创建MySqlDataReader。

·         ExecuteScalar:执行查询,并返回查询操作所返回的结果集中第1行的第1列。多余的列或行将被忽略。

·         Prepare:在MySQL服务器的1个实例上创建命令的预制版本。

26.2.3.1.3. 用法
在下面的示例中,创建了1个MySqlCommand和1个MySqlConnection。打开了MySqlConnection,并将其设置为用于MySqlCommand的连接。随后,调用ExecuteNonQuery,并关闭连接。为了完成该任务,为ExecuteNonQuery传递了1个连接字符串和1个查询字符串(查询字符串是1条SQL INSERT语句)。
26.2.3.1.3.1. VB.NET

在下例中,介绍了在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
26.2.3.1.3.2. C#

在下例中,介绍了在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();
}

26.2.3.2. MySqlCommandBuilder类

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的关联,已生成的命令将不再使用。

26.2.3.2.1. 属性

可用属性如下:

·         DataAdapter:MySqlCommandBuilder将自己注册为针对RowUpdating事件的监听程序,RowUpdating事件是由在该属性中指定的MySqlDataAdapter生成的。创建了新的MySqlCommandBuilder实例时,将释放任何已有的与MySqlDataAdapter关联的MySqlCommandBuilder。

·         QuotePrefix, QuoteSuffix:MySQL中的数据库对象能够包含特殊字符,如空格等,这会使得正常的SQL字符串无法解析。使用QuotePrefix和QuoteSuffix属性,MySqlCommandBuilder能够创建处理该问题的SQL命令。

26.2.3.2.2. 方法

可用方法如下:

·         DeriveParameters:从MySqlCommand指定的存储程序中检索参数信息,并填充所指定MySqlCommand对象的参数集。目前不支持该方法,这是因为MySQL中未提供存储程序。

·         GetDeleteCommand:获取用于在数据库上执行删除操作所需的、自动生成的MySqlCommand对象。

·         GetInsertCommand:获取用于在数据库上执行插入操作所需的、自动生成的MySqlCommand对象。

·         GetUpdateCommand:获取用于在数据库上执行更新操作所需的、自动生成的MySqlCommand对象。

·         RefreshSchema:刷新用于生成INSERT、UPDATE或DELETE语句的数据库方案信息。

26.2.3.2.3. 用法
在下面给出的示例中,使用了MySqlCommand、MySqlDataAdapter和MySqlConnection,用于从数据源选择行。为该示例传递了1个初始化的DataSet、1个连接字符串、1个查询字符串(是SQL SELECT语句)、以及1个作为数据库表名称的字符串。随后,该示例创建了1个MySqlCommandBuilder。
26.2.3.2.3.1. VB.NET

在下例中,介绍了在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
    
26.2.3.2.3.2. C#

在下例中,介绍了在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;
    }  
    

26.2.3.3. MySqlConnection类

MySqlConnection对象代表与MySQL服务器数据源的会话。创建MySqlConnection实例时,所有属性均将被设置为它们的初始值。关于这些值的列表,请参见MySqlConnection构造函数。

如果MySqlConnection超出范围,不会被关闭。因此,必须通过调用Close或Dispose明确地关闭连接。

26.2.3.3.1. 属性
可用属性如下:

·         ConnectionString:设置或获取用于连接至MySQL服务器数据库的字符串。

·         ConnectionTimeout:获取在中止尝试并生成错误之前为建立连接所需的等待时间。

·         Database:获取当前数据库的名称或打开连接后将使用的数据库的名称。

·         DataSource:获取将要连接的MySQL服务器的名称。

·         ServerThread:返回该连接所使用的服务器线程的ID。

·         ServerVersion:获取包含客户端与之相连的MySQL服务器版本的字符串。

·         State:获取连接的当前连接的状态。

·         UseConnection:与服务器进行通信时,指明该连接是否将使用压缩特性。

26.2.3.3.2. 方法
可用方法如下:

·         BeginTransaction:开始数据库事务。

·         ChangeDatabase:针对打开的MySqlConnection,更改当前数据库。

·         Close:关闭与数据库的连接。这是关闭任何打开连接的首选方法。

·         CreateCommand:创建并返回与MySqlConnection相关的MySqlCommand对象。

·         Dispose:释放MySqlConnection使用的资源。

·         Open:用ConnectionString指定的属性设置打开数据库连接。

·         Ping:对MySQL服务器执行Ping操作。

26.2.3.3.3. 用法
在下面的示例中,创建了1个MySqlCommand和1个MySqlConnection。打开了MySqlConnection,并将其设置为用于MySqlCommand的连接。随后,调用ExecuteNonQuery,并关闭连接。为了完成该任务,为ExecuteNonQuery传递了1个连接字符串和1个查询字符串(查询字符串是1条SQL INSERT语句)。
26.2.3.3.3.1. VB.NET

在下例中,介绍了在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
      
26.2.3.3.3.2. C#

在下例中,介绍了在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();
}

      

26.2.3.4. MySqlDataAdapter类

MySQLDataAdapter起着DataSet和MySQL之间桥梁的作用,用于检索和保存数据。MySQLDataAdapter通过映射Fill(填充)和Update(更新)提供了该桥,Fill能改变DataSet中的数据以便与数据源中的数据匹配,Update能改变数据源中的数据以便与DataSet中的数据匹配(通过对数据源使用恰当的SQL语句)。

当MySQLDataAdapter填充DataSet时,如果表或列不存在,它将为返回的数据创建必要的表和列。但是,在隐式创建的方案中不包括主键信息,除非将MissingSchemaAction属性设为AddWithKey。在使用FillSchema用数据填充它之前,也能让MySQLDataAdapter创建DataSet方案,包含主键信息。

MySQLDataAdapter用于MySqlConnection和MySqlCommand的连接,用以提升连接至MySQL数据库时的性能。

MySQLDataAdapter还包括SelectCommand、InsertCommand、DeleteCommand、UpdateCommand和TableMappings属性,用于简化数据的加载和更新操作。

26.2.3.4.1. 属性

可用属性如下:

·         AcceptChangesDuringFill:获取或设置值,该值指明了在任何填充操作过程中,在将DataRow添加到DataTable后,是否要在DataRow上调用AcceptChanges。

·         ContinueUpdateOnError:获取或设置值,该值指定了在行更新过程中出现错误时是否要生成异常项。

·         DeleteCommand:获取或设置用于将记录从数据集中删除的SQL语句或存储程序。

·         InsertCommand:获取或设置用于在数据集中插入记录的SQL语句或存储程序。

·         MissingMappingAction:确定当进入的数据不含匹配表或列时需要采取的动作。

·         MissingSchemaAction:确定当已有的DataSet方案与进入数据不匹配时需要采取的动作。

·         SelectCommand:获取或设置用于在数据源中选择记录的SQL语句或存储程序。

·         TableMappings:获取提供了源表和DataTable之间主映射的集合。

·         UpdateCommand:获取或设置用于在数据源中更新记录的SQL语句或存储程序。

26.2.3.4.2. 方法
可用方法如下:

·         Fill:使用DataSet名称添加或刷新DataSet中的行,以便与数据源中的行匹配,并创建名为“Table”的DataTable。

·         FillSchema:将名为“Table”的DataTable添加到指定的DataSet,并配置方案,以便与基于指定SchemaType的数据源中的表匹配。

·         GetFillParameters:执行SQL SELECT语句时,按用户获取参数集。

·         Update:为指定DataSet中的各插入行、更新行或删除行分别调用INSERT、UPDATE或DELETE语句。

26.2.3.4.3. 用法
在下面的示例中,创建了1个MySqlCommand和1个MySqlConnection。打开MySqlConnection,并将其设置为用于MySqlCommand的连接。随后,调用ExecuteNonQuery,并关闭连接。为了完成该任务,为ExecuteNonQuery传递了1个连接字符串和1个查询字符串(查询字符串是1条SQL INSERT语句)。
26.2.3.4.3.1. VB.NET

在下例中,介绍了在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 
26.2.3.4.3.2. C#

在下例中,介绍了在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;
}   
  

26.2.3.5. MySqlDataReader类

MySqlDataReader类提供了从MySQL数据库读取行的“仅正向”流的一种方式。

要想创建MySQLDataReader,必须调用MySqlCommand对象的ExecuteReader方法,而不是直接使用构造函数。

使用MySqlDataReader的同时,相关的MySqlConnection将忙于MySqlDataReader。除了关闭它之外,不能在MySqlConnection上执行任何操作。该情况将一直持续到调用了MySqlDataReader的“Close”方法为止。

关闭了MySqlDataReader后,你只能调用IsClosed和RecordsAffected属性。尽管在MySqlDataReader存在同时能够访问RecordsAffected属性,但在返回RecordsAffected的值之前总应调用“Close”,以确保准确的返回值。

为了获得最佳性能,MySqlDataReader将避免创建不必要的对象或执行不必要的数据拷贝。其结果是,对诸如GetValue等方法的多个调用会返回对相同对象的引用。如果你准备更改由诸如GetValue等方法返回的对象的基本值,请仔细小心。

26.2.3.5.1. 属性
可用属性如下:

·         Depth:获取指明当前行嵌套深度的值。目前并不支持方法,总会返回0。

·         FieldCount:获取当前行中的列数。

·         HasRows:获取值,该值指明了MySqlDataReader是否包含1行或多行。

·         IsClosed:获取值,该值指明了和苏剧阅读器是否已关闭。

·         Item:以固有格式获取列的值。在C#,该属性是MySqlDataReader类的索引属性。

·         RecordsAffected:获取隐执行SQL语句而更改、插入、或删除的行数。

26.2.3.5.2. 方法
可用方法如下:

·         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跳到下一条记录。

26.2.3.5.3. 用法
在下面的示例中,创建了1个MySqlConnection,1个MySqlCommand和1个MySqlDataReader。该示例读取数据,并将数据输出到控制台。最后,本例关闭了MySqlDataReader,然后关闭了MySqlConnection。
26.2.3.5.3.1. VB.NET

在下例中,介绍了在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       
      
26.2.3.5.3.2. C#

在下例中,介绍了在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();
 }     
      

26.2.3.6. MySqlException类

当MySql数据提供方遇到服务器生成的错误时将创建该类。

抛出异常时,打开的连接不会自动关闭。如果客户端应用程序判定该异常是致命的,应关闭任何打开的MySqlDataReader对象或MySqlConnection对象。

26.2.3.6.1. 属性
可用属性如下:

·         HelpLink:获取或设置指向与该异常相关的帮助文件的链接。

·         InnerException:获取导致当前异常的异常实例。

·         IsFatal:如果该异常是致命的,为“真”,并关闭连接,如果不是致命的,为“假”。

·         Message:获取描述当前异常的消息。

·         Number:获取指明错误类型的编号。

·         Source:获取或设置导致错误的应用程序或对象的名称。

·         StackTrace:获取抛出当前异常时在调用堆栈上帧的字符串表征。

·         TargetSite:获取抛出当前异常的方法。

26.2.3.6.2. 方法
MySqlException类没有相应的方法。
26.2.3.6.3. 用法
在下述示例中,因丢失了服务器而生成了MySqlException,然后显示异常。
26.2.3.6.3.1. VB.NET

该示例介绍在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       
      
26.2.3.6.3.2. C#

该示例介绍在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 );
   }
}
    

26.2.3.7. MySqlHelper类

助手类,能使与提供方(Provider)一起进行的工作变的更简单。开发人员可以使用该类提供的方法自动执行共同任务。
26.2.3.7.1. 属性
MySqlHelper类没有相应的属性。
26.2.3.7.2. 方法
可用方法如下:

·         ExecuteDataRow:执行单个SQL语句并返回结果集的第1行。在该方法的执行过程中,将创建、打开并关闭1个新的MySqlConnection对象。

·         ExecuteDataset:执行单个SQL命令并返回DataSet中的结果集。在该方法的执行过程中,将创建、打开并关闭1个新的MySqlConnection对象。

·         ExecuteNonQuery:在MySQL数据库上执行单个命令。调用该方法时,将认为MySqlConnection已打开,方法执行完后,MySqlConnection仍保持打开状态。

·         ExecuteReader:Overloaded:在MySQL数据库上执行单个命令。

·         ExecuteScalar:在MySQL数据库上执行单个命令。

·         UpdateDataSet:用来自给定DataSet的数据更新给定表。

26.2.3.8. MySqlTransaction类

代表将在MySQL数据库中进行的SQL事务。
26.2.3.8.1. 属性
可用属性如下:

·         Connection:获取与事务相关的MySqlConnection对象,如果事务不再有效,获取空引用(在Visual Basic中为Nothing)。

·         IsolationLevel:为该事务指定IsolationLevel。

26.2.3.8.2. 方法
可用方法如下:

·         Commit:提交数据库事务。

·         Rollback:从挂起状态回滚事务。

26.2.3.8.3. 用法
在下面的示例中,创建了1个MySqlConnection和1个MySqlTransaction。此外,在示例中还介绍了如何使用BeginTransaction、Commit和Rollback方法。
26.2.3.8.3.1. VB.NET

在下例中,介绍了在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       
      
26.2.3.8.3.2. C#

在下例中,介绍了在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();
    }
}       
      

26.2.4. 使用MySQL Connector/NET

26.2.4.1. 前言

在本节中,介绍的Connector/NET的一些常用方式,包括BLOB处理,日期处理,以及与诸如Crystal Reports等常见工具一起使用Connector/NET的方法。

26.2.4.2. 使用MySQL Connector/NET连接到MySQL

26.2.4.2.1. 前言
.NET应用程序和MySQL服务器之间的所有交互均是通过MySqlConnection对象传送的。在应用程序能够与服务器进行交互之前,必须获取、配置、并打开MySqlConnection对象。

即使在使用MySqlHelper类时,MySqlConnection对象也会被Helper类创建。

在本节中,介绍了使用MySqlConnection对象连接到MySQL的方法。

26.2.4.2.2. 创建连接字符串

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, AddrNetwork Address。

·         Uid:连接时使用的MySQL用户账户。别名包括User Id, UsernameUser name。

·         Pwd:MySQL账户的密码。也可以使用别名密码。

·         Database:所有语句作用于的默认数据库。默认为mysql。也可以使用别名Initial Catalog

·         Port:MySQL用于监听连接的端口。默认为3306。将该值指定为“-1将使用命名管道连接。

26.2.4.2.3. 打开连接

一旦创建了连接字符串,可使用它打开与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);
}
一旦打开了连接,其他MySQL Connector/NET类也能使用该连接与MySQL服务器进行通信。
26.2.4.2.4. 处理连接错误

由于与外部服务器的连接不可预测,应为你的.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");
    }
}
  

26.2.4.3. 与预处理语句一起使用MySQL Connector/NET

26.2.4.3.1. 前言
从MySQL 4.1开始,能够与MySQL Connector/NET一起使用预处理语句。使用预处理语句能够现住改善多次执行的查询的性能。

对于多次执行的语句,预处理执行的速度快于直接执行,这是因为只需进行1次解析操作。在直接执行的情况下,每次执行时均将进行解析操作。预处理执行还能降低网络通信量,这是因为对于预处理语句的每次执行,仅需发送用于参数的数据。

预处理语句的另一优点是,它能使用二进制协议,这使得客户端和服务器间的数据传输更有效率。

26.2.4.3.2. 在MySQL Connector/NET中准备语句
为了准备好语句,需创建1个命令对象,并为查询设置.CommandText属性。

输入语句后,调用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);
}

26.2.4.4. 用MySQL Connector/NET访问存储程序

26.2.4.4.1. 前言

随着MySQL版本5的发布,MySQL服务器目前支持存储程序,它采用了SQL 2003存储程序的语法。

 

存储程序指的是能够保存在服务器上的一组SQL语句。 一旦完成了该操作,客户端无需再次发出单独语句,而仅需引用存储程序取而代之。

在下述情况下,存储程序尤其有用:

·         多个客户端应用程序是采用不同语言编写的或工作在不同平台上,但需执行相同的数据库操作。

·         安全性极其重要时。例如,对于所有共同操作,银行采用了存储程序。这样,就能提供一致且安全的环境,而且这类存储程序能够保证每次操作均具有恰当登录。在这类设置下,应用程序和用户无法直接访问数据库表,但能执行特定的存储程序。

MySQL Connector/NET支持通过MySqlCommand对象的存储程序调用。使用MySqlCommand.Parameters集,能够将数据传入和传出MySQL存储程序。

在本节中,未深度介绍创建存储程序方面的信息,要想了解这类信息,请参见MySQL参考手册的存储程序

在MySQL Connector/NET安装的Samples目录下,可找到1个相应的示例,该示例演示了与MySQL Connector/NET一起使用存储程序的方法。

26.2.4.4.2. 从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);
}
请注意,不同于命令行和GUI客户端,在MySQL Connector/NET中创建存储程序时不需要指定特殊的定界符。
26.2.4.4.3. 从MySQL Connector/NET调用存储程序

要想使用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);
}
一旦调用了存储程序,可使用MySqlConnector.Parameters集的.Value属性检索输出参数的值。

26.2.4.5. 用Connector/NET处理BLOB数据

26.2.4.5.1. 前言
MySQL的1种用途是在BLOB列中保存二进制数据。MySQL支持4种不同的BLOB数据类型:TINYBLOB, BLOB, MEDIUMBLOBLONGBLOB

可使用Connector/NET访问保存在BLOB列中的数据,并能使用客户端代码对这类数据进行操作。使用Connector/NET和BLOB数据时,无特殊要求。

在本节中,给出了数个简单的代码示例,在MySQL Connector/NET安装的Samples目录下,可找到1个完整的示例应用程序。

26.2.4.5.2. 准备MySQL服务器
与BLOB数据一起使用MySQL的第1步是配置服务器。首先,让我们从创建要访问的表开始。在我的文件表中,通常有4列:1个具有恰当大小的AUTO_INCREMENT列(UNSIGNED SMALLINT),用于保存识别文件的主键;1个VARCHAR列,用于保存文件名;1个UNSIGNED MEDIUMINT列,用于保存文件的大小;以及1个用于保存文件本身的MEDIUMBLOB列。对于本例,我将使用下述表定义:
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数据需要一段时间。恰当地设置该值,使之与预期使用相符,并在必要时增大该值。

26.2.4.5.3. 将文件写入数据库

要想将文件写入数据库,需要将文件转换为字节数组,然后将字节数组用作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);
}
 
FileStream对象的Read方法可用于将文件加载到字节数组中,该字节数组的大小是根据FileStream对象的Length属性确定的。

将字节数组指定为MySqlCommand对象的参数后,调用ExecuteNonQuery方法,并将BLOB插入到文件表中。

26.2.4.5.4. 将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对象中。使用MySqlDataReader的GetBytes方法将BLOB加载到字节数组,然后使用FileStream对象将字节数据写入磁盘。

MySqlDataReader的GetOrdinal方法可用于确定命名列的整数索引。如果SELECT查询的列顺序发生变化,使用GetOrdinal方法能够防止错误。

26.2.4.6. 与Crystal Reports一起使用MySQL Connector/NET

26.2.4.6.1. 前言
Crystal Reports是Windows应用程序开发人员用于通报文档生成的常用工具。在本节中,介绍了Crystal Reports XI与MySQL和Connector/NET一起使用的方法。

在MySQL Connector/NET安装的Samples目录的CrystalDemo子目录下,可找到完整的示例应用程序。

26.2.4.6.2. 创建数据源

在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);
}
设计报告时,可将该代码生成的XML文件用作ADO.NET XML数据源。

如果你选择使用Connector/ODBC来设计报告,可从dev.mysql.com下载它。

26.2.4.6.3. 创建报告
对于大多数应用目的,标准的报告向导应能帮助你完成报告的最初创建。要想启动向导,打开Crystal Reports并从“文件”菜单选择“New > Standard Report”选项。

向导首先要求你提供数据源。如果你正使用Connector/ODBC作为数据源,选择数据源时,请使用OLE DB (ADO)树的“用于ODBC的OLEDB provider”选项,,而不是来自ODBC (RDO)的对应选项。如果你使用的是已保存的数据集,请选择ADO.NET (XML)选项,并浏览你保存的数据集。

在报告的创建过程中,剩余部分将由向导自动完成。

创建完报告后,选择“文件”菜单中的“Report Options...”菜单项。取消对“Save Data With Report”(与报告一起保存数据)选项的选择。这样,就能防止保存的数据干扰应用程序中的数据加载操作。

26.2.4.6.4. 显示报告

要想显示报告,首先用报告所需的数据填充数据集,然后加载报告,并将其与绑定到数据集。最后,将报告传递给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);
}  
 
应将SELECT语句按字母顺序排列,这点很重要,原因在于,这是报告希望其源表所具有的顺序。对于报告中的每个表,均需要一条SetDataSource语句。

该方法会导致性能问题,这是因为Crystal Reports必须在客户端一侧将表绑定在一起,与使用以前保存的数据集相比,速度较慢。

26.2.4.7. 在MySQL Connector/NET中处理日期和时间信息

26.2.4.7.1. 前言
MySQL和.NET语言处理日期和时间信息的方式是不同的,MySQL允许使用无法由.NET数据类型表示的日期,如“0000-00-00 00:00:00如果处理步当,该差异会导致问题。

在本节中,介绍了使用MySQL Connector/NET时恰当处理日期和时间信息的方法。

26.2.4.7.2. 使用无效日期时的问题
对于使用无效日期的开发人员来说,数据处理方面的差异会导致问题。无效的MySQL日期无法被加载到.NET DateTime对象中,包括NULL日期。

由于该原因,不能用MySqlDataAdapter类的Fill方法填充.NET DataSet对象,这是因为无效日期会导致System.ArgumentOutOfRangeException异常。

26.2.4.7.3. 限制无效日期
对日期问题的最佳解决方案是,限制用户输入无效日期。这即可在客户端上进行,也可在服务器端进行。

在客户端上限制无效日期十分简单,即总使用.NET DateTime类来处理日期。DateTime类仅允许有效日期,从而确保了数据库中的值也是有效的。该方法的缺点是,在使用.NET和非.NET代码操作数据库的混合环境下不能使用它,这是因为各应用程序必须执行自己的日期验证。

MySQL 5.0.2和更高版本的用户可使用新的传统SQL模式来限制无效日期值。关于使用传统SQL模式的更多信息,请参见http://dev.mysql.com/doc/mysql/en/server-sql-mode.html

26.2.4.7.4. 处理无效日期
强烈建议在你的.NET应用程序中应避免使用无效日期,尽管如此,也能tongguo MySqlDateTime数据类型使用无效日期。

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时,会导致错误。

由于存在上述已知事宜,最佳建议仍是,在你的应用程序中仅使用有效日期。

26.2.4.7.5. 处理NULL日期

.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;
  
NULL值能够在数据集中使用,也能将其绑定以构成控件,无需特殊处理。
阅读(2897) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~