王朝网络
分享
 
 
 

XML 与 XML DB 和 ODP.NET 结合使用

王朝c#·作者佚名  2008-05-31
宽屏版  字体: |||超大  

作者:Mark A. Williams了解如何将 XML 与 Oracle 数据库、Oracle XML DB 和 Oracle Data Provider for .NET 结合使用。

许多开发人员已经意识到,并且更多的开发人员正开始意识到 Oracle 数据库与 .NET 应用程序结合将形成了一个强大的组合。Oracle 数据库众多强大特性之一就是能够使用 XML。利用 Oracle Data Provider for .NET (ODP.NET) 和 Oracle XML DB,通过 Visual Studio.NET 应用程序在 Oracle 数据库中使用 XML 数据就和使用传统数据类型一样轻易。(关于使用 Oracle 进行一般的 .NET 开发的介绍,请参见 John Paul Cook 的文章“在 Oracle 数据库上构建 .NET 应用程序”。关于使用 XML 和 Oracle Data Provider for .NET. 的其他示例,请参见“ODP.NET 的 XML 支持”页面。) 本文介绍了利用 ODP.NET 和 Visual Studio .NET 在 Oracle 数据库中使用 XML 数据的基础知识,并非凡介绍了 将 XML 模式加载到数据库中 将 XML 实例文档加载到数据库中 创建在 XML 数据上执行 DML 操作的 .NET 应用程序。 为了成功实施本文中的代码,您需要能够访问安装了 XML DB 的 Oracle9i Release 2 或更高版本的数据库、Visual Studio.NET、Oracle 10g 客户端软件和 ODP.NET 10g。(Oracle 数据库 10g 下载包括 ODP.NET。) 在本文中,我创建了一个名为“OTNXML”的数据库用户来演示 XML 数据的使用。假如您没有足够的权限在数据库中创建拥有相应权限的用户,那么您需要与您的数据库治理员协作来完成这个任务。我将本文分解为一系列易于理解的步骤,并从创建数据库用户开始。 注重:创建新用户不是严格必需的 — 假如您已经有了一个拥有与第 1 步中列出的权限(或更高权限)的用户,那么您可以在本文中可以使用该用户。当然,您也可以为现有用增加缺少的权限。例如,OE 用户(Oracle 示例模式的一部分)拥有除 create any Directory 和 drop any directory 权限外的所有必要权限。第 1 步:创建数据库用户 为了为本文创建数据库用户,请使用 SQL*Plus 以治理用户(拥有 DBA 角色的用户)身份登录数据库,并执行以下语句:

-- create the database user

-- adjust tablespace names as necessary for your environment

create user otnxml identified by demo

default tablespace users

temporary tablespace temp

quota unlimited on users;

一旦创建了用户,则授予其相应的权限和角色。我选择了仅授予必要的系统权限,而不是授予“传统的”connect 和 resource 角色。

-- grant system privileges and roles to the user

grant create session,

alter session,

create table,

create trigger,

create type,

create any directory,

drop any directory,

xdbadmin

to otnxml;

虽然这些权限大部分您都应当很熟悉,以下摘要用来强调它们的目的和指出它们在本文中的用途: create session— 该权限答应用户创建与数据库的会话。没有该权限,用户将无法连接(或登录)数据库。 alter session— 该权限答应用户改变与数据库会话相关的属性。这是成功执行 registerSchema 过程的必要权限。 create table— 该权限答应用户在数据库中创建表。 create trigger— 该权限答应用户在其拥有的表上创建触发器。 create type— 该权限答应用户在数据库中创建新类型。XML 元素将利用类型保存在数据库中。 create any directory— 该权限答应用户创建目录对象。目录对象将用来将 XML 实例文档加载到数据库中。这是一种非常强大的权限,应当仅授予可信任的用户。因为目录对象存在于数据库内部的系统命名空间中,因此必须使用“any”要害字。没有用户级的“create directory”权限。 drop any directory— 该权限是与 create any directory 权限相对应的权限。它答应用户删除目录对象。与 create any directory 权限类似,由于其系统级属性,该权限应当仅授予可信任的用户。 xdbadmin role — 该权限答应用户在 XML DB 引擎中创建目录

注重:由于 create any directory 和 drop any directory 权限提升的权力,您可能希望在完成本文之后撤销这些权限(假如您不删除用户的话)。您可能还希望删除您将创建的目录对象。 第 2 步:创建 XML 模式 因为 XML 模式文档是基于文本的文档,因此您可以使用任何文本编辑器来创建它。还有各种工具可以图形化地创建和处理该模式文档。然而,为了使本文集中笔墨介绍通过 .NET 在 Oracle 数据库内部使用 XML,而非介绍 XML 编辑和治理工具,我使用了 Notepad 来创建下面这个简单的模式文件,我将其命名为“Player.xsd”。该模式和相关的数据代表一个简单的“player”实体,例如足球队的一名运动员。

<?xml version="1.0"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xdb="http://xmlns.oracle.com/xdb"

xdb:storeVarrayAsTable="true"

version="1.0" >

<xsd:element name="Player" xdb:defaultTable="PLAYER">

<xsd:complexType xdb:SQLType="PLAYER_T">

<xsd:sequence>

<xsd:element name="PlayerName" type="xsd:string" minOccurs="1"

xdb:SQLName="PLAYER_NAME" />

<xsd:element name="PlayerPosition" type="xsd:string" minOccurs="1"

xdb:SQLName="PLAYER_POSITION" />

<xsd:element name="PlayerNumber" type="xsd:positiveInteger"

minOccurs="1" xdb:SQLName="PLAYER_NUMBER" />

<xsd:element name="PlayerClub" type="xsd:string" minOccurs="1"

xdb:SQLName="PLAYER_CLUB" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

XML 模式文档是基本的模式文档,可能有一点例外:它包含 Oracle XML DB 批注。批注是 World Wide Web Consortium (W3C) XML 模式建议的一部分,它们支持将供给商特定的信息添加到模式定义中。批注还答应覆盖 XML 类型和 SQL 类型之间的默认映射。这是批注在本模式文档中的主要用途。为了使用 XML DB 批注,必须在文档的根元素下指定命名空间。这由以下文本(摘自模式文档)来实现:

xmlns:xdb="http://xmlns.oracle.com/xdb"

正如您看到的那样,我决定了使用文本“xdb”作为整个模式文档命名空间的缩写标识符。为了将集合存储为嵌套表,将以下文本包含在文档根元素中。

xdb:storeVarrayAsTable="true"

为了指定在数据库内部用来保存数据的表的名称,我在根元素定义中包含了以下文本:

xdb:defaultTable="PLAYER"

注重:默认表由 Oracle 创建,并且必须不能是现有表的名称。例如,您不能“预先创建”该表并告诉 Oracle 将数据加载到其中。 该批注指示数据库中的 XML DB 引擎:用来存储该模式所提供数据的表的名称应为“PLAYER”。其余的批注在名称和功能方面非常简单。“SQLName”批注指示表中的列名,“SQLType”批注相应地指示列数据类型或数据库类型对象。例如,以下文本指示,XML 复杂类型应当以名为“PLAYER_T”的数据库类型存储在数据库中:

xdb:SQLType="PLAYER_T"

第 3 步:注册 XML 模式文档 为了在数据库中的 XML DB 中注册 XML 模式文档,请将“Player.xsd”文件保存在一个您有读/写权限的文件夹中。用 XML DB 将文件加载到数据库中的方式有多种。我将利用一个目录对象和 DBMS_XMLSCHEMA PL/SQL 程序包来演示该过程。 注重:该目录对象必须代表一个数据库可访问的操作系统目录。 以 OTNXML 用户身份连接数据库,创建一个目录对象,该目录对象将代表 XML 模式和实例文档所在的操作系统目录。

-- create the directory object that represents the directory

-- where the schema and instance documents reside

create directory OTNXML_DIR as 'C:\My Projects\OTN\XML Schema\XML';

使用 DBMS_XMLSCHEMA 程序包在 XML DB 中注册 XML 模式。

-- register the xml schema with xml db

begin

dbms_xmlschema.registerSchema(

schemaurl=>'http://localhost:8080/home/OTNXML/source/xsd/Player.xsd',

schemadoc=>bfilename('OTNXML_DIR','Player.xsd'),

local=>TRUE,

gentypes=>TRUE,

genbean=>FALSE,

force=>FALSE,

owner=>'OTNXML',

csid=>nls_charset_id('AL32UTF8')

);

end;

/

现在已经成功在数据库中注册了该模式,您可以查看在注册过程中为您创建的对象。这些对象名称和类型是在模式定义文件中包含的批注以及系统生成的名称和类型的一个结果。例如,在第 2 步中,您指定了复杂类型的默认类型应当存储在称为“PLAYER_T”的 Oracle 类型中。下面您可以看到 Oracle 已经为您创建了该类型。

select object_name,

object_type,

status

from user_objects

order by object_name,

object_type;

Results of the statement:

OBJECT_NAME OBJECT_TYPE STATUS

-------------------------------- ------------------- -------

EXTRADATA177_L LOB VALID

NAMESPACES178_L LOB VALID

PLAYER TABLE VALID

PLAYER$xd TRIGGER VALID

PLAYER_T TYPE VALID

SYS_C004803 INDEX VALID

SYS_XDBPD6_L LOB VALID

7 rows selected.

第 4 步:加载 XML 实例文档 为了演示加载 XML 实例文档,我创建了一个符合在“Player.xsd”文件中所指定模式的小文件。与“Player.xsd”文件类似,该文件同样是一个使用 Notepad 创建的简单文本文件。“Player.xml”文件的内容如下:

<?xml version="1.0"?>

<Player

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation=

"http://localhost:8080/home/OTNXML/source/xsd/Player.xsd">

<PlayerName>Steven Gerrard</PlayerName>

<PlayerPosition>Midfield</PlayerPosition>

<PlayerNumber>8</PlayerNumber>

<PlayerClub>Localhost</PlayerClub>

</Player>

该文件通过在文档的根元素中包含以下文本被指定为 XML 实例文档:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

此外,您可以看到在文档根元素中还引用了刚才注册的模式:

xsi:noNamespaceSchemaLocation=

"http://localhost:8080/home/OTNXML/source/xsd/Player.xsd">

我选择在与模式文档相同的目录(在我的机器上为“C:\My Projects\OTN\XML Schema\XML”)中创建 XML 实例文档以重用目录对象。可用下列语句加载实例文档:

insert into player

values

(

XMLType

(

bfilename('OTNXML_DIR','Player.xml'),

nls_charset_id('AL32UTF8')

)

);

注重:请务必在加载数据后执行 commit。 为了快速验证数据是否已加载,您可以在 SQL*Plus 中输入下列语句:

select object_value from player;

Results of the statement:

OBJECT_VALUE

-------------------------------------------------------------------------------

<?xml version="1.0"?>

<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://localhost:8080/home/OTNXML/source/xsd/Player.xsd">

<PlayerName>Steven Gerrard</PlayerName>

<PlayerPosition>Midfield</PlayerPosition>

<PlayerNumber>8</PlayerNumber>

<PlayerClub>Localhost</PlayerClub>

</Player>

1 row selected.

正如您所看到的那样,该语句生成了数据的 XML 表示(即实例文档)。 第 5 步:在 XML 数据上执行 DML 操作 您已经完成了所有的安装工作,现在该运行 Visual Studio.NET,创建一个在数据库中操作 XML 数据的应用程序了。在运行 Visual Studio.NET 之后,创建一个新的 Windows Forms 项目,然后在项目中添加一个对 Oracle Data Provider for .NET 的引用。应用程序包含一个简单的表单,该表单将用来执行以下任务: 连接数据库 检索运动员 插入运动员 更新运动员 删除运动员

我将先提供完成这些任务的代码。在提供代码之后,我将实际演示该应用程序。为了执行这些任务,请创建类似下面的一个表单: 当然,执行这些操作的第一步是创建一个到数据库的连接。我已经创建了一个表单级的字段,该字段代表连接。该字段被声明为:

// C#:

private OracleConnection conn;

'// VB.NET:

Private conn As OracleConnection

该字段在表单加载事件中进行初始化(如下):

// C#:

private void MainForm_Load(object sender, System.EventArgs e)

{

// create new instance of Oracle Connection class

conn = new OracleConnection();

}

'// VB.NET:

Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'// create new instance of Oracle Connection class

conn = New OracleConnection

End Sub

Connect 按钮背后的代码将创建到数据库的连接。这些代码本质上相当于样板。它以您先前创建的 OTNXML 用户的身份创建一个到数据库的连接。一旦成功连接,它就将禁用 Connect 按钮,启用其余按钮(我创建这些按钮时将它们禁用了),最后显示一条消息,表明成功建立了一个连接。假如出现异常,该代码将显示一个基本消息框,指示出现了什么异常。

// C#:

private void BTnConnect_Click(object sender, System.EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

// adjust the connection string as necessary for your environment

string connstr = "User Id=OTNXML; PassWord=DEMO; Data Source=ORANET";

// set the connection string value for the connection object

conn.ConnectionString = connstr;

// attempt to open the connection

// if failure display error message

// if sUCcess display simple success message

try

{

conn.Open();

}

catch (Exception ex)

{

MessageBox.Show(this, ex.Message, Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

finally

{

if (conn.State == ConnectionState.Open)

{

// disable the connect button

btnConnect.Enabled = false;

// enable the remaining buttons

btnGetPlayer.Enabled = true;

btnInsertPlayer.Enabled = true;

btnUpdatePlayer.Enabled = true;

btnDeletePlayer.Enabled = true;

MessageBox.Show(this, "Successfully connected to database.",

Application.ProductName, MessageBoxButtons.OK,

MessageBoxIcon.Information);

}

}

Cursor.Current = Cursors.Default;

}

'// VB.NET:

Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click

Cursor.Current = Cursors.WaitCursor

'// adjust the connection string as necessary for your environment

Dim connstr As String = "User Id=OTNXML; Password=DEMO; Data Source=ORANET"

'// set the connection string value for the connection object

conn.ConnectionString = connstr

'// attempt to open the connection

'// if failure display error message

'// if success display simple success message

Try

conn.Open()

Catch ex As Exception

MessageBox.Show(Me, ex.Message, Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Error)

Finally

If (conn.State = ConnectionState.Open) Then

'// disable the connect button

btnConnect.Enabled = False

'// enable the remaining buttons

btnGetPlayer.Enabled = True

btnInsertPlayer.Enabled = True

btnUpdatePlayer.Enabled = True

btnDeletePlayer.Enabled = True

MessageBox.Show(Me, "Successfully connected to database.",

Application.ProductName, MessageBoxButtons.OK,

MessageBoxIcon.Information)

End If

End Try

Cursor.Current = Cursors.Default

End Sub

在与数据库连接之后,您可以检索一个运动员(比如说在上一步中加载的那个)。Get Player 按钮背后的代码将根据运动员的名称来检索运动员。检索运动员的 SQL 语句将把运动员作为关系数据进行检索,而不是检索 XML 文档本身。您将看到在代码中使用 XML 文档来插入运动员的一个示例。

// C#:

private void btnGetPlayer_Click(object sender, System.EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

// build the sql statement to retrieve the xml

// data as relational data

StringBuilder sbSQL = new StringBuilder();

sbSQL.Append("select extractvalue(object_value, '/Player/PlayerPosition'), ");

sbSQL.Append(" extractvalue(object_value, '/Player/PlayerNumber'), ");

sbSQL.Append(" extractvalue(object_value, '/Player/PlayerClub') ");

sbSQL.Append("from player ");

sbSQL.Append("where existsNode(object_value, :1) = 1");

// create an input parameter for the player name

OracleParameter p1 = new OracleParameter();

p1.OracleDbType = OracleDbType.Varchar2;

p1.Direction = ParameterDirection.Input;

p1.Value = "/Player[PlayerName=\"" + txtPlayerName.Text + "\"]";

OracleCommand cmd = new OracleCommand();

cmd.CommandText = sbSQL.ToString();

cmd.Connection = conn;

cmd.Parameters.Add(p1);

OracleDataReader dr = cmd.ExecuteReader();

if (dr.Read())

{

// assign the values to the text boxes

txtPlayerPosition.Text = dr[0].ToString();

txtPlayerNumber.Text = dr[1].ToString();

txtPlayerClub.Text = dr[2].ToString();

dr.Close();

}

else

{

MessageBox.Show(this, "Player Not Found", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);

}

dr.Dispose();

cmd.Dispose();

Cursor.Current = Cursors.Default;

}

'// VB.NET:

Private Sub btnGetPlayer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetPlayer.Click

Cursor.Current = Cursors.WaitCursor

'// build the sql statement to retrieve the xml

'// data as relational data

Dim sbSQL As StringBuilder = New StringBuilder

sbSQL.Append("select extractvalue(object_value, '/Player/PlayerPosition'), ")

sbSQL.Append(" extractvalue(object_value, '/Player/PlayerNumber'), ")

sbSQL.Append(" extractvalue(object_value, '/Player/PlayerClub') ")

sbSQL.Append("from player ")

sbSQL.Append("where existsNode(object_value, :1) = 1")

'// create input parameter for the player name

Dim p1 As OracleParameter = New OracleParameter

p1.OracleDbType = OracleDbType.Varchar2

p1.Direction = ParameterDirection.Input

p1.Value = "/Player[PlayerName=""" + txtPlayerName.Text + """]"

Dim cmd As OracleCommand = New OracleCommand

cmd.CommandText = sbSQL.ToString()

cmd.Connection = conn

cmd.Parameters.Add(p1)

Dim dr As OracleDataReader = cmd.ExecuteReader()

If (dr.Read()) Then

'// assign the values to the text boxes

txtPlayerPosition.Text = dr(0).ToString()

txtPlayerNumber.Text = dr(1).ToString()

txtPlayerClub.Text = dr(2).ToString()

dr.Close()

Else

MessageBox.Show(Me, "Player Not Found", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

dr.Dispose()

cmd.Dispose()

Cursor.Current = Cursors.Default

End If

End Sub

该应用程序提供了将运动员插入到数据库中的功能,Ins Player 按钮背后的代码将插入一个符合您创建并加载到 XML DB 信息库中的 XML 模式的新 XML 实例文档。在创建了 XML 实例文档之后,代码将把保存该文档的变量绑定到一个典型的 insert 语句中,执行 insert 操作,显示一条成功或异常消息。

// C#:

private void btnInsertPlayer_Click(object sender, System.EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

// create the xml document

StringBuilder xmlDocument = new StringBuilder();

xmlDocument.Append("<?xml version=\"1.0\"?>");

xmlDocument.Append("<Player");

xmlDocument.Append("xmlns:xsi=

\"http://www.w3.org/2001/XMLSchema-instance\"");

xmlDocument.Append("xsi:noNamespaceSchemaLocation=

\"http://localhost:8080/home/OTNXML/source/xsd/Player.xsd\">");

xmlDocument.Append(" <PlayerName>" + txtPlayerName.Text + "</PlayerName>");

xmlDocument.Append("<PlayerPosition>" + txtPlayerPosition.Text +

"</PlayerPosition>");

xmlDocument.Append("<PlayerNumber>" + txtPlayerNumber.Text +

"</PlayerNumber>");

xmlDocument.Append(" <PlayerClub>" + txtPlayerClub.Text + "</PlayerClub>");

xmlDocument.Append("</Player>");

// create command object and set properties

OracleCommand cmd = new OracleCommand();

cmd.Connection = conn;

cmd.CommandText = "insert into player values (:1)";

// create an input parameter to hold the xml document

OracleParameter p = new OracleParameter();

p.Direction = ParameterDirection.Input;

p.Value = xmlDocument.ToString();

cmd.Parameters.Add(p);

// execute the insert

// display message if failure

try

{

cmd.ExecuteNonQuery();

MessageBox.Show(this, "Player Inserted.", Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Information);

}

catch (Exception ex)

{

MessageBox.Show(this, ex.Message, Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Error);

}

p.Dispose();

cmd.Dispose();

Cursor.Current = Cursors.Default;

}

'// VB.NET:

Private Sub btnInsertPlayer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsertPlayer.Click

Cursor.Current = Cursors.WaitCursor

'// create the xml document

Dim xmlDocument As StringBuilder = New StringBuilder

xmlDocument.Append("<?xml version=""1.0""?>")

xmlDocument.Append("<Player")

xmlDocument.Append("xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""")

xmlDocument.Append("xsi:noNamespaceSchemaLocation=

""http://localhost:8080/home/OTNXML/source/xsd/Player.xsd"">")

xmlDocument.Append("<PlayerName>" + txtPlayerName.Text + "</PlayerName>")

xmlDocument.Append("<PlayerPosition>" + txtPlayerPosition.Text +

"</PlayerPosition>")

xmlDocument.Append("<PlayerNumber>" + txtPlayerNumber.Text +

"</PlayerNumber>")

xmlDocument.Append("<PlayerClub>" + txtPlayerClub.Text + "</PlayerClub>")

xmlDocument.Append("</Player>")

'// create command object and set properties

Dim cmd As OracleCommand = New OracleCommand

cmd.Connection = conn

cmd.CommandText = "insert into player values (:1)"

'// create an input parameter to hold the xml document

Dim p As OracleParameter = New OracleParameter

p.Direction = ParameterDirection.Input

p.Value = xmlDocument.ToString()

cmd.Parameters.Add(p)

'// execute the insert

'// display message if failure

Try

cmd.ExecuteNonQuery()

MessageBox.Show(Me, "Player Inserted.", Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Information)

Catch ex As Exception

MessageBox.Show(Me, ex.Message, Application.ProductName,

MessageBoxButtons.OK, MessageBoxIcon.Error)

p.Dispose()

cmd.Dispose()

End Try

Cursor.Current = Cursors.Default

End Sub

与插入运动员的代码类似,Updt Player 按钮背后的代码将创建一个 XML 实例文档,将其与 SQL 语句中的一个占位符变量绑定,并执行该语句来更新运动员。SQL 语句在 where 子句中使用运动员的名称来确定更新哪个运动员。更新实际上是用一个新的包含更新数据的 XML 实例文档替换现有的 XML 实例文档。代码完成后将显示一条简单的成功或异常消息。

// C#:

private void btnUpdatePlayer_Click(object sender, System.EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

// create the xml document that contains the changes

StringBuilder xmlDocument = new StringBuilder();

xmlDocument.Append("<?xml version=\"1.0\"?>");

xmlDocument.Append("<Player");

xmlDocument.Append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");

xmlDocument.Append(" xsi:noNamespaceSchemaLocation=\"http://localhost:8080/home/OTNXML/source/xsd/Player.xsd\">");

xmlDocument.Append(" <PlayerName>" + txtPlayerName.Text + "</PlayerName>");

xmlDocument.Append(" <PlayerPosition>" + txtPlayerPosition.Text + "</PlayerPosition>");

xmlDocument.Append(" <PlayerNumber>" + txtPlayerNumber.Text + "</PlayerNumber>");

xmlDocument.Append(" <PlayerClub>" + txtPlayerClub.Text + "</PlayerClub>");

xmlDocument.Append("</Player>");

StringBuilder sbSQL = new StringBuilder();

sbSQL.Append("update player ");

sbSQL.Append("set object_value = :1 ");

sbSQL.Append("where existsNode(object_value, :2) = 1");

// create an input parameter to hold the xml document

OracleParameter p1 = new OracleParameter();

p1.OracleDbType = OracleDbType.Varchar2;

p1.Direction = ParameterDirection.Input;

p1.Value = xmlDocument.ToString();

// create an input parameter for the player name

OracleParameter p2 = new OracleParameter();

p2.OracleDbType = OracleDbType.Varchar2;

p2.Direction = ParameterDirection.Input;

p2.Value = "/Player[PlayerName=\"" + txtPlayerName.Text + "\"]";

// create command object and set properties

OracleCommand cmd = new OracleCommand();

cmd.Connection = conn;

cmd.CommandText = sbSQL.ToString();

cmd.Parameters.Add(p1);

cmd.Parameters.Add(p2);

// execute the update

// display message if failure

try

{

cmd.ExecuteNonQuery();

MessageBox.Show(this, "Player Updated.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);

}

catch (Exception ex)

{

MessageBox.Show(this, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);

}

p2.Dispose();

p1.Dispose();

cmd.Dispose();

Cursor.Current = Cursors.Default;

}

'// VB.NET:

Private Sub btnUpdatePlayer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdatePlayer.Click

Cursor.Current = Cursors.WaitCursor

'// create the xml document that contains the changes

Dim xmlDocument As StringBuilder = New StringBuilder

xmlDocument.Append("<?xml version=""1.0""?>")

xmlDocument.Append("<Player")

xmlDocument.Append(" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""")

xmlDocument.Append(" xsi:noNamespaceSchemaLocation=""http://localhost:8080/home/OTNXML/source/xsd/Player.xsd"">")

xmlDocument.Append(" <PlayerName>" + txtPlayerName.Text + "</PlayerName>")

xmlDocument.Append(" <PlayerPosition>" + txtPlayerPosition.Text + "</PlayerPosition>")

xmlDocument.Append(" <PlayerNumber>" + txtPlayerNumber.Text + "</PlayerNumber>")

xmlDocument.Append(" <PlayerClub>" + txtPlayerClub.Text + "</PlayerClub>")

xmlDocument.Append("</Player>")

Dim sbSQL As StringBuilder = New StringBuilder

sbSQL.Append("update player ")

sbSQL.Append("set object_value = :1 ")

sbSQL.Append("where existsNode(object_value, :2) = 1")

'// create an input parameter to hold the xml document

Dim p1 As OracleParameter = New OracleParameter

p1.OracleDbType = OracleDbType.Varchar2

p1.Direction = ParameterDirection.Input

p1.Value = xmlDocument.ToString()

'// create an input parameter for the player name

Dim p2 As OracleParameter = New OracleParameter

p2.OracleDbType = OracleDbType.Varchar2

p2.Direction = ParameterDirection.Input

p2.Value = "/Player[PlayerName=""" + txtPlayerName.Text + """]"

'// create command object and set properties

Dim cmd As OracleCommand = New OracleCommand

cmd.Connection = conn

cmd.CommandText = sbSQL.ToString()

cmd.Parameters.Add(p1)

cmd.Parameters.Add(p2)

'// execute the update

'// display message if failure

Try

cmd.ExecuteNonQuery()

MessageBox.Show(Me, "Player Updated.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)

Catch ex As Exception

MessageBox.Show(Me, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

p1.Dispose()

p2.Dispose()

cmd.Dispose()

End Try

Cursor.Current = Cursors.Default

End Sub

该应用程序提供的最后的 DML 操作是删除运动员的功能。与 retrieve 和 update 代码类似,这些代码使用运动员的名称作为确定对哪个运动员执行该操作的基础。

// C#:

private void btnDeletePlayer_Click(object sender, System.EventArgs e)

{

Cursor.Current = Cursors.WaitCursor;

// build the delete statement

StringBuilder sbSQL = new StringBuilder();

sbSQL.Append("delete ");

sbSQL.Append("from player ");

sbSQL.Append("where existsNode(object_value, :1) = 1");

// create an input parameter for the player name

OracleParameter p1 = new OracleParameter();

p1.OracleDbType = OracleDbType.Varchar2;

p1.Direction = ParameterDirection.Input;

p1.Value = "/Player[PlayerName=\"" + txtPlayerName.Text + "\"]";

// create command object and set properties

OracleCommand cmd = new OracleCommand();

cmd.Connection = conn;

cmd.CommandText = sbSQL.ToString();

cmd.Parameters.Add(p1);

// execute the delete

try

{

cmd.ExecuteNonQuery();

MessageBox.Show(this, "Player Deleted.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);

}

catch (Exception ex)

{

MessageBox.Show(this, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);

}

cmd.Dispose();

Cursor.Current = Cursors.WaitCursor;

}

'// VB.NET:

Private Sub btnDeletePlayer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeletePlayer.Click

Cursor.Current = Cursors.WaitCursor

'// build the delete statement

Dim sbSQL As StringBuilder = New StringBuilder

sbSQL.Append("delete ")

sbSQL.Append("from player ")

sbSQL.Append("where existsNode(object_value, :1) = 1")

'// create an input parameter for the player name

Dim p1 As OracleParameter = New OracleParameter

p1.OracleDbType = OracleDbType.Varchar2

p1.Direction = ParameterDirection.Input

p1.Value = "/Player[PlayerName=""" + txtPlayerName.Text + """]"

'// create command object and set properties

Dim cmd As OracleCommand = New OracleCommand

cmd.Connection = conn

cmd.CommandText = sbSQL.ToString()

cmd.Parameters.Add(p1)

'// execute the delete

Try

cmd.ExecuteNonQuery()

MessageBox.Show(Me, "Player Deleted.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)

Catch ex As Exception

MessageBox.Show(Me, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)

cmd.Dispose()

End Try

Cursor.Current = Cursors.WaitCursor

End Sub

为了清除该表单,Reset 按钮背后的代码将简单地将文本框的值设为空字符串。

// C#:

private void btnReset_Click(object sender, System.EventArgs e)

{

// "clear" the text box values

txtPlayerName.Text = "";

txtPlayerPosition.Text = "";

txtPlayerNumber.Text = "";

txtPlayerClub.Text = "";

// assign focus to the player name text box

txtPlayerName.Focus();

}

'// VB.NET:

Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click

'// "clear" the text box values

txtPlayerName.Text = ""

txtPlayerPosition.Text = ""

txtPlayerNumber.Text = ""

txtPlayerClub.Text = ""

'// assign focus to the player name text box

txtPlayerName.Focus()

End Sub

正如您可能预料到的那样,Close 按钮背后的代码仅执行表单关闭。

// C#:

private void btnClose_Click(object sender, System.EventArgs e)

{

// simply close the form

this.Close();

}

'// VB.NET:

Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click

'// simply close the form

Me.Close()

End Sub

表单关闭事件中的代码将检查数据库连接对象是否处于打开状态;假如是,则将关闭并删除该对象。

// C#:

private void MainForm_Closing(object sender,

System.ComponentModel.CancelEventArgs e)

{

if (conn.State == ConnectionState.Open)

{

// close connection and dispose connection object

conn.Close();

conn.Dispose();

conn = null;

}

}

'// VB.NET:

Private Sub MainForm_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

If (conn.State = ConnectionState.Open) Then

'// close connection and dispose connection object

conn.Close()

conn.Dispose()

conn = Nothing

End If

End Sub

第 6 步:运行应用程序 现在您已经创建和加载了 XML 模式和 XML 实例文档,并创建了应用程序,现在该看看它实际工作的情形了。当应用程序启动时,表单的初始外观将与下面类似: 在您单击 Connect 按钮之后,表单将显示一个消息框,指示成功建立连接,并且应启用了“DML 按钮”: 要查看您在第 5 步中为 XML 实例文档加载的运动员数据,请用运动员的名称(Steven Gerrard,假如您使用与我相同数据的话)填充 Player Name 文本框,并单击 Get Player 按钮: 要创建新运动员,您可以单击 Reset 按钮,然后在文本框中输入新信息,或者简单地替换现有文本: 一旦您对各种运动员属性的值感到满足,即可单击 Ins Player 按钮。包含运动员信息的新 XML 实例文档将被插入到数据库中,并显示一个消息框: 要更新运动员,您可以只要修改属性(运动员名称除外)即可。例如,我将运动员的号码更改为 100: 单击 Updt Player 按钮,更新数据库中的数据: 不幸地是,我似乎不符合 Localhost Football Club 的要求,因此我必须删除我自己。为了删除运动员,只需单击 Del Player 按钮即可: 要验证运动员是否已被删除,请单击 Reset 按钮,然后在 Player Name 文本框中输入运动员名称: 现在,单击 Get Player 按钮将显示一个消息框,指示找不到请求的运动员: 当您完成测试时,单击 Close 按钮,终止应用程序。 总结 在本文中,我向您介绍了如何在 XML DB 信息库中加载和注册 XML 模式文档,以及如何将符合模式的 XML 实例文档加载到数据库中。然后我创建了一个简单的 Windows 表单应用程序,它在 XML 数据上执行 DML 操作。最后我演练了该应用程序的使用。这些信息将使您能开始从您基于 Oracle 的 .NET 应用程序在数据库中使用 XML 数据。 Mark A. Williams 是《.NET 专家 Oracle 编程》(Apress,2004 年 11 月)的作者,目前在医疗诊断行业担任 Production DBA。他自从 Oracle 数据库的 7.0.1.16 版本起一直在使用 Oracle 产品,并且是版本 7、8、8i 和 9i 的 Oracle 认证数据库治理员专家。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有