技术开发 频道

我与Db2 9新特性的零距离体验



    DB2 9中新特性概述
    经过长达 5 年的开发,IBM DB2 9 将传统的高性能、易用性与自描述、灵活的 XML 相结合,转变成为交互式、充满活力的数据服务器。其中DB2 9的一个最主要的特性就是借助 pureXML® 技术提升 XML 应用性能,节约开发时间和成本。

    那么什么是pureXML呢?我们知道在过去我们将XML 数据存储为大对象文本或分散到关系表,这种方式并不能适应灵活的业务需求。DB2 9 的 pureXML 特性革新了 XML 文档的处理方式——将 XML 作为新的数据类型存储在原生的层次性模型之中。
pureXML 对于 XML 与关系数据的无缝集成通过灵活的 XML 索引、SQL 与 XQuery 查询接口加速了应用开发、提高了搜索性能。

    DB2 以 XML 数据自身固有的分层格式存储和处理这些数据,避免因为将 XML 存储为 CLOB 中的文本或将它映射为关系表而导致的性能和灵活性限制。与仅使用 XML 的数据库不同,DB2 V9 还提供了关系型数据与 XML 数据在数据库中的无缝集成 —— 甚至是表的某一行中的集成。这样的灵活性表现在语言支持中,使您可访问关系型数据、XML 数据,或者同时访问这两种数据。

    在这篇文章中,我们将会向大家展示如何操作DB2 9中的新的XML数据类型。我们将通过一个示例来展示如何操作DB2 9中的XML数据类型。

    准备工作:
    1.创建数据对象
    为了操作方便,我们使用DB2 9中的SAMPLE数据库,在这里说明一点,在DB2 Viper中只有Unicode 数据库才能同时存储 XML 文档和 SQL 数据的更多传统格式,比如整数、日期/时间、变长字符串,等等。随后,您将在这个数据库中创建对象来管理 XML 和其他类型的数据。

    2.创建数据表
    由于我们使用的是SAMPLE数据库,该数据库中有一张CUSTOMER表,CUSTOMER表中有三个字段,其字段名称和数据类型如图所示:

   该表中有两个XML的字段,实际上DB2使用了不同的存储方案来存储 XML 和非 XML 数据。另外,对XML的数据类型并没有进行XML文档内部结构的定义,即,用户不需要为了存储数据而预定义一个 XML 数据结构(或者,更准确地说是一个 XML 模式)。事实上,DB2 可以在一个单独的列中存储任何格式良好的 XML 文档,这意味着不同模式的 XML 文档 —— 或没有和任何注册的模式关联的文档 —— 都可以存储在相同的 DB2 列中。

    至此,我们需要的数据库及其表已经准备就绪,接下来我们就看如何对CUSTOMER这张表中的XML数据类型进行操作了。



    连接操作

    DB2与JDBC
    为了连接数据库,需要使用DB2 JDBC技术,依照 JDBC 规范,有四种类型的 JDBC 驱动程序体系结构: 

    Type 1:这类驱动程序将 JDBC API 作为到另一个数据访问 API 的映射来实现,如开放式数据库连通性(Open Database Connectivity,ODBC)。这类驱动程序通常依赖本机库,这限制了其可移植性。JDBC-ODBC 桥驱动程序就是 Type 1 驱动程序的最常见的例子。

    Type 2:这类驱动程序部分用 JAVA 编程语言编写,部分用本机代码编写。这些驱动程序使用特定于所连接数据源的本机客户端库。同样,由于使用本机代码,所以其可移植性受到限制。

    Type 3:这类驱动程序使用纯 JAVA 客户机,并使用独立于数据库的协议与中间件服务器通信,然后中间件服务器将客户机请求传给数据源。

    Type 4:这类驱动程序是纯 JAVA,实现针对特定数据源的网络协议。客户机直接连接至数据源。

    其中COM.ibm.db2.jdbc.app.DB2Driver和COM.ibm.db2.jdbc.net.DB2Driver
    都在db2java.zip文件中,可以把他改名成db2java.jar文件使用。 通用驱动程序,放在文件db2jcc.jar文件中。

    这三种驱动的程序加载和连接建立方法如下:
//Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); //Class.forName("COM.ibm.db2.jdbc.net.DB2Driver"); //Class.forName("com.ibm.db2.jcc.DB2Driver"); //连接例子可以相同,都是指定主机,端口和数据库名称 String dbUrl ="jdbc:db2://localhost:6789/sample"; con = DriverManager.getConnection(dbUrl,"www","123456");
    连接的例子
    在这里我们使用的是通用驱动程序,并采用配置文件的形式,其配置文件是db2Conn.properties。在该配置文件里有连接数据库的地址,用户名,密码和数据库名等。其代码如下:
# Properties file for java xml samples # Created on Nov 3, 2004 # Description: file containing the value that automate the execution and testing of functions #rollbackCommit=rollback #interactive=yes # Modify the following according to your machine log in hostName=localhost portNumber=50000 password=lys databaseName=SAMPLE userName=Administrator # Modify the following to test different situations #purchaseOrder_id=1020 #pID=100-101-01 fileName=F:\\eclipse\\WorkPlace\\DB2XML\\src\\p5.xml
读取配置文件和连接数据库的类(db2Conn.java)代码如下:

/* * Created on Jul 8, 2004 * */ /** * File: db2Conn.java * * Desc: Utility Class for establishing DB2 connection via JCC Type 4 Driver */ import java.sql.*; public class db2Conn { /** * Default Constructor */ public db2Conn() {} /* * Get Database connection using Database name, username, password, machine name and port number */ public static Connection get(String db, String userName, String passwd, String host, String port){ Connection conn=null; try { /** Load the DB2(R) JCC driver with DriverManager **/ Class.forName("com.ibm.db2.jcc.DB2Driver"); /** Create Database URL and establish DB Connection **/ String databaseURL = "jdbc:db2://"+host+":"+port+"/"+db; java.util.Properties properties = new java.util.Properties (); properties.setProperty ("user", userName); properties.setProperty ("password", passwd); conn = DriverManager.getConnection(databaseURL,properties); /** print any error messages **/ if(conn==null)System.out.println("Connection Failed \n"); }catch (ClassNotFoundException e) { System.out.println("Exception in DB2Connection"); e.printStackTrace(); }catch (java.sql.SQLException e) { e.printStackTrace(); System.exit(-1); } return conn; } }


    插入操作
    执行插入操作的类为insertxml.java,该程序读取一个XML文件,该XML文件包括对客户的描述信息,如:客户的地址信息、电话、传真等。并将该XML文件的内容插入到CUSTOMER表中的XML类型的字段。
insertxml.java其代码如下:
package xml; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Properties; public class Test2 { /** * @param args */ /** private members **/ private static Connection conn; static Properties db2ConnProps = new Properties(); static Properties fileinputProps = new Properties(); public static void main(String[] args) throws FileNotFoundException, IOException, SQLException { String db, userName, passwd, host, port; host=port=db=userName=passwd=null; /* load the contents of properties file in case of missing arguments*/ db2ConnProps.load(new FileInputStream ("F:\\eclipse\\WorkPlace\\DB2XML\\src\\db2Conn.properties")); db=db2ConnProps.getProperty("databaseName"); userName=db2ConnProps.getProperty("userName"); passwd=db2ConnProps.getProperty("password"); host=db2ConnProps.getProperty("hostName"); port=db2ConnProps.getProperty("portNumber"); /** connect to the database **/ conn=db2Conn.get(db,userName,passwd,host,port); int id = 99;//由于id是主键,所以该id不能相同,如连续插入多次,可以修改id的值或者在数据库中将CUSTOMER表中的id字段设置为自动增长。 String fn = "F:\\eclipse\\WorkPlace\\DB2XML\\src\\Client8877.xml"; String sqls = "insert into customer ( cid, info) values (?, ?)"; File file = new File(fn); try { PreparedStatement insertStmt = conn.prepareStatement(sqls); conn.setAutoCommit(true); insertStmt.setInt(1, id); insertStmt.setBinaryStream(2, new FileInputStream(file), (int) file .length()); if (insertStmt.executeUpdate() == 1) { System.out.println("insertBinStream:: No record inserted."); } insertStmt.executeUpdate(); } catch (RuntimeException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { conn.close(); } } }


    查询操作
    查询xml字段的类为readxml.java,该类通过提供cid来查询客户表中的info字段并产生xml文件。
package xml; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; public class readxml { private static Connection conn; static Properties db2ConnProps = new Properties(); private static PreparedStatement poStmt; private static ResultSet rs; static Properties fileinputProps = new Properties(); public static void main(String[] args) throws FileNotFoundException, IOException, SQLException { String db, userName, passwd, host, port,description; host = port = db = userName = passwd = null; /* load the contents of properties file in case of missing arguments*/ db2ConnProps.load(new FileInputStream( "F:\\eclipse\\WorkPlace\\DB2XML\\src\\db2Conn.properties")); db = db2ConnProps.getProperty("databaseName"); userName = db2ConnProps.getProperty("userName"); passwd = db2ConnProps.getProperty("password"); host = db2ConnProps.getProperty("hostName"); port = db2ConnProps.getProperty("portNumber"); /** connect to the database **/ conn = db2Conn.get(db, userName, passwd, host, port); int id = 99; String fn = "F:\\eclipse\\WorkPlace\\DB2XML\\src\\Client8877.xml"; String sqls = "insert into customer ( cid, info) values (?, ?)"; File file = new File(fn); try { System.out.print(getDescription("88")); } catch (RuntimeException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { conn.close(); } } public static String getDescription(String cid) { String description; description=null; try { poStmt = conn.prepareStatement("Select INFO from CUSTOMER where cid=?"); poStmt.setString(1,cid); rs= poStmt.executeQuery(); if(rs.next()) { description=rs.getString(1); } else System.out.println(" Customer info not found.\n"); } catch(SQLException sqle) { System.out.println("Error Msg: "+ sqle.getMessage()); System.out.println("SQLState: "+sqle.getSQLState()); System.out.println("SQLError: "+sqle.getErrorCode()); System.out.println("Rollback the transaction and quit the program"); System.out.println(); try {conn.setAutoCommit(false);} catch (java.sql.SQLException e) { e.printStackTrace(); System.exit(-1); } try { conn.rollback(); } catch (Exception e) { JdbcException jdbcExc = new JdbcException(e, conn); jdbcExc.handle(); } System.exit(1); } return description; } }



    其他查询操作


    SQL 程序员常常编写根据某种条件限制从 DBMS 返回的行的查询。例如,SQL 查询限制从 "CUSTOMER" 表中检索的行,使之只包括那些具有某种状态的客户。在这个例子中,客户的状态可在 SQL VARCHAR 列中捕捉。但是,如果您想根据某种应用于 XML 列中数据的条件对搜索进行限制,那么应该怎么做呢?SQL/XML 的 XMLExists 函数为完成该任务提供了一种手段。 

    通过 XMLExists 可以在 XML 文档中找到一个元素,并测试它是否满足某个特定的条件。如果用在 WHERE 子句中,则 XMLExists 可以限制返回的结果,使之只包括那些包含具有特定 XML 元素值的 XML 文档的行(换句话说,指定的值等于 "true")。

     例如您想找到居住在具有特定邮政编码的地区的所有客户的姓名。您也许还记得," CUSTOMER " 表的一个 XML 列中存储了客户的地址(包括邮政编码)。通过使用 XMLExists,可以从 XML 列中搜索目标邮政编码,并相应地限制返回的结果集。下面的 SQL/XML 查询返回居住在邮政编码为 95116 的地区的客户的姓名:
    根据 XML 元素值限制结果
1select name from CUSTOMER 2where xmlexists('$c/Client/Address[zip="95116"]' 3passing CUSTOMER.INFO as "c") 4
    如果我们想将 XML 值投影到返回的结果集。换句话说,我们要从 XML 文档中检索一个或多个元素值。有很多方法可以做这件事。首先我们使用 XMLQuery 函数来检索一个元素的值,然后使用 XMLTable 函数来检索多个元素的值,然后将这些映射到一个 SQL 结果集的列。
    比如如何创建一个列出 具有某种状态的客户的 email 地址的报告。我们可以通过XMLQuery 函数来完成这项任务:
检索符合条件的客户的 email 信息
select xmlquery('$c/Client/email' passing info as "c") from CUSTOMER where status = 'good'
    更新操作
    DB2 允许用 SQL UPDATE 语句或通过使用系统提供的存储过程(DB2XMLFUNCTIONS.XMLUPDATE)来更新 XML 列。不管使用哪种方式,对 XML 列的更新都发生在元素级。然而,使用存储过程更新 XML 数据的程序员不需要提供整个 XML 文档给 DB2;他们只需指定要更新的 XML 元素。发出 UPDATE 语句的程序员则需要指定整个文档(而不仅仅是要更改的元素)。
例如,如果要发出一条 UPDATE 语句来更改某个特定客户的联系方式信息中的 email 地址,就必须在 XML 列中提供全部联系方式信息,而不仅仅是新的 email 元素值。
update clients set contactinfo=( xmlparse(document '<email>newemail@someplace.com</email>' ) ) where id = 3227
    本例中更新xml类型字段的类为updatexml.java,该类通过提供cid来更新CUSTOMER表中的客户信息。

    更新操作

    DB2 允许用 SQL UPDATE 语句或通过使用系统提供的存储过程(DB2XMLFUNCTIONS.XMLUPDATE)来更新 XML 列。不管使用哪种方式,对 XML 列的更新都发生在元素级。然而,使用存储过程更新 XML 数据的程序员不需要提供整个 XML 文档给 DB2;他们只需指定要更新的 XML 元素。发出 UPDATE 语句的程序员则需要指定整个文档(而不仅仅是要更改的元素)。
例如,如果要发出一条 UPDATE 语句来更改某个特定客户的联系方式信息中的 email 地址,就必须在 XML 列中提供全部联系方式信息,而不仅仅是新的 email 元素值。
update clients set contactinfo=( xmlparse(document '<email>newemail@someplace.com</email>' ) ) where id = 3227
    本例中更新xml类型字段的类为updatexml.java,该类通过提供cid来更新CUSTOMER表中的客户信息。

import java.sql.*; import java.io.*; import java.util.*; import org.xml.sax.*; import javax.xml.parsers.*; import org.apache.xerces.dom.DOMImplementationImpl; import org.w3c.dom.*; import org.apache.xml.serialize.*; public class updatexml { /** private members **/ private static Connection conn; private static PreparedStatement sStmt; private static PreparedStatement uStmt; private static ResultSet rs; /*needed for properties file*/ static Properties db2ConnProps = new Properties(); static Properties fileinputProps = new Properties(); /* Default Constructor */ public updatexml() {} /* Main Driver*/ public static void main(String[] args) { String db,pID, userName, passwd, host, port, pInfo, input, newDoc, xpath, fileName; String inputfile = " "; boolean inputfilevalidate=false; String rollbackCommit="rollback"; String interactive = ""; boolean exit, update; boolean validate=false; exit=update=false; int option; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String [] productInfo = {"name", "details", "price", "weight" }; String [] productValues = new String[4]; newDoc=pInfo=host=port=db=pID=userName=passwd=input=null; /** print user options **/ try { /* load the contents of properties file in case of missing arguments*/ db2ConnProps.load(new FileInputStream ("F:\\eclipse\\WorkPlace\\DB2XML\\src\\db2Conn.properties")); db=db2ConnProps.getProperty("databaseName"); userName=db2ConnProps.getProperty("userName"); passwd=db2ConnProps.getProperty("password"); host=db2ConnProps.getProperty("hostName"); port=db2ConnProps.getProperty("portNumber"); rollbackCommit=db2ConnProps.getProperty("rollbackCommit"); interactive=db2ConnProps.getProperty("interactive"); /** establish DB connection **/ conn=db2Conn.get(db,userName,passwd,host,port); try {conn.setAutoCommit(false);} catch (java.sql.SQLException e) { e.printStackTrace(); System.exit(-1); } /* prints current connection status*/ System.out.println(); System.out.println(" This sample updates xml information from a table."); System.out.println(); System.out.println(" Connect to '"+db+"' database using JDBC Universal type 4 driver"); System.out.println(" Connection: com.ibm.db2.jcc"); try { db2ConnProps.load(new FileInputStream ("F:\\eclipse\\WorkPlace\\DB2XML\\src\\db2Conn.properties"));} catch(IOException io) {System.out.println(io.getMessage());} catch(NullPointerException ne) {System.out.println("NullPointerException");} /** get product id if not interactive, else request user input**/ if (interactive.equals("no")) { pID = db2ConnProps.getProperty("pID"); System.out.println(); System.out.println(" Using default product ID of "+pID); } else { pID=db2ConnProps.getProperty("pID"); System.out.println(); System.out.print(" Enter Product ID #[default is '1000']:"); pID = br.readLine(); } /*If user just presses enter, then use default value*/ if(pID.length()==0) { System.out.println(" Nothing entered, thus, using default value."); pID=db2ConnProps.getProperty("pID"); } else; /** prompt for valid product ID **/ while((pInfo=getProduct(pID))==null) { System.out.println(); System.out.println(" No Such Product ID can be found. Do you want to use default"); System.out.print(" value of "+db2ConnProps.getProperty("pID")+" [y/n] or q to quit: "); input=br.readLine(); /** if update, parse and update new product **/ if(input.equals("y") || input.equals("Y")) { pID=db2ConnProps.getProperty("pID"); System.out.println(); System.out.println(" Now using pid="+pID); } else if(input.equals("q") || input.equals("Q")) { System.out.println(" Quitting program! "); System.exit(-1); } else { System.out.println(); System.out.print(" Please re-enter Product #: "); pID = br.readLine(); } }//end while /** insert product info into a DOM and use DOM API to extract element values **/ domUtility.initializeFromString(pInfo); /** Print the product description currently **/ System.out.println(); System.out.println(" Current contents of DESCRIPTION in the PRODUCTS table"); System.out.println(" for pid='"+pID+"'"); System.out.println(); System.out.println(domUtility.toString("/product")); /** print product update options **/ printProduct(productInfo); if (interactive.equals("no")) { System.out.println(" Just changing #[4] weight"); input = "4"; } else { input = ""; } while(!(input.equals("0") | input.equals("1") | input.equals("2") | input.equals("3") | input.equals("4"))) { System.out.println(); System.out.print(" Enter # of the Item to change (or zero to quit): "); input =br.readLine(); } option= Integer.parseInt(input); /** update product value or exit **/ while(!(option == 0)) { System.out.println(); switch (option) { case 0: exit=true; break ; case 1: System.out.print(" Enter new Value for \"name\": "); input=br.readLine(); domUtility.setValue("/product/description/name/text()",input); break; case 2: System.out.print(" Enter new Value for \"details\": "); input=br.readLine(); domUtility.setValue("/product/description/details/text()",input); break; case 3: System.out.print(" Enter new Value for \"price\": "); input=br.readLine(); domUtility.setValue("/product/description/price/text()",input); break; case 4: if (interactive.equals("no")) { input="5"; System.out.println(); System.out.println(" Using default Product Weight of 5."); System.out.println(); option = 0; } else { System.out.print(" Enter new Value for \"weight\": "); input=br.readLine(); } domUtility.setValue("/product/description/weight/text()",input); break; default: System.out.print(" Invalid Entry, please try again"); break; }//end switch /** select next item to update **/ if (interactive.equals("no")) { input = "0"; } else { input = ""; printProduct(productInfo); } while(!(input.equals("0") | input.equals("1") | input.equals("2") | input.equals("3") | input.equals("4"))) { System.out.print(" Enter # of the Item to change (or zero to quit): "); input =br.readLine(); } option= Integer.parseInt(input); }//end while(!(option == 0)) System.out.println(); System.out.println(" Updating the record in the Products table using the above data"); System.out.println(" updateProd(domUtility.toString(\"/product\"),pID)"); System.out.println(); updateProd(domUtility.toString("/product"),pID); /** Print the product description currently--before rollback **/ pInfo=getProduct(pID); domUtility.initializeFromString(pInfo); System.out.println(" After update, contents of DESCRIPTION in the PRODUCTS table"); System.out.println(" for pid='"+pID+"'"); System.out.println(); System.out.println(domUtility.toString("/product")); //rollback and then print the contents if (rollbackCommit.equals("rollback")) { System.out.println(" Rollback the transaction."); try { conn.rollback(); } catch (Exception e) { JdbcException jdbcExc = new JdbcException(e, conn); jdbcExc.handle(); } } else ; /** Print the product description currently--After rollback **/ pInfo=getProduct(pID); domUtility.initializeFromString(pInfo); System.out.println(); System.out.println(" After rollback, contents of DESCRIPTION in the PRODUCTS table"); System.out.println(" for pid='"+pID+"'"); System.out.println(); System.out.println(domUtility.toString("/product")); /** close connections **/ try {conn.commit();} catch(SQLException ex) { System.err.println("SQLException information"); while(ex!=null) { System.err.println ("Error msg: " + ex.getMessage()); System.err.println ("SQLSTATE: " + ex.getSQLState()); System.err.println ("Error code: " + ex.getErrorCode()); ex.printStackTrace(); ex = ex.getNextException(); // For drivers that support chained exceptions } } System.out.println(" Disconnect from the '"+db+"' database"); closeConn(); System.out.println(" Disconnected."); } catch(NullPointerException ne){System.out.println("NullPointerException main");} catch(IOException io){io.printStackTrace();} }//main public static void setConn(Connection c) { conn=c; } /* Get product from database */ public static String getProduct(String pID) { String pInfo=null; try { /** Prepare Statement **/ sStmt= conn.prepareStatement("Select INFO from CUSTOMER where cid=?"); sStmt.setString(1,pID); rs=sStmt.executeQuery(); if (rs.next()) { pInfo=rs.getString(1); } else; } catch(SQLException sqle) { System.out.println("Error Msg: "+ sqle.getMessage()); System.out.println("SQLState: "+sqle.getSQLState()); System.out.println("SQLError: "+sqle.getErrorCode()); System.out.println("Rollback the transaction and quit the program"); System.out.println(); try { conn.rollback(); } catch (Exception e) { JdbcException jdbcExc = new JdbcException(e, conn); jdbcExc.handle(); } System.out.println(); System.exit(1); } return pInfo; }//end getProduct /* Update Product */ public static void updateProd(String newDoc, String pID) { int recordUpdated=0; try { /** Prepare Statement **/ uStmt= conn.prepareStatement("Update CUSTOMER set INFO = ? where PID=?"); uStmt.setString(1,newDoc); uStmt.setString(2,pID); if(uStmt.executeUpdate()!=1) System.out.println("Product could not be updated"); else ; } catch(SQLException sqle) { System.out.println("Error Msg: "+ sqle.getMessage()); System.out.println("SQLState: "+sqle.getSQLState()); System.out.println("SQLError: "+sqle.getErrorCode()); System.out.println("Rollback the transaction and quit the program"); System.out.println(); try { conn.rollback(); } catch (Exception e) { JdbcException jdbcExc = new JdbcException(e, conn); jdbcExc.handle(); } System.exit(1); } }//end updateProd /* Print Product Update Values */ public static void printProduct(String [] pInfo) { String pValue, xpath; pValue = xpath = null; System.out.println(); System.out.println(" Product ID="+domUtility.getValue("/product/@pid")+"\n"); for(int i=0; i < pInfo.length; i++) { xpath="/Client/description/"+pInfo[i]+"/text()"; pValue = domUtility.getValue(xpath); if(pValue != null) System.out.println(" ["+(i+1)+"] "+pInfo[i].toString()+" : "+ pValue); } }//end printProduct /* Close conections */ public static void closeConn() { try { conn.close(); sStmt.close(); uStmt.close(); } catch(SQLException sqle) { System.out.println(sqle.getMessage()); System.out.println(sqle.getSQLState()); System.out.println(sqle.getErrorCode()); } }//end closeConn }
    删除 XML 数据
    删除包含 XML 列的行很简单。SQL DELETE 语句允许通过 WHERE 子句识别(或限制)要删除的行。该子句可以包括简单的谓词来标识非 XML 列值或包括 SQL/XML 函数来标识包含在 XML 列中的 XML 元素值。

    例如,下面展示了如何删除客户 CID 为 3227 的客户的所有信息:
delete from CUSTOMER
where cid = 1000

    还记得怎样限制 SQL SELECT 语句,使之仅返回居住在邮政编码为 95116 的地区的客户的行吗?如果还记得的话,很容易知道如何删除与那些客户相关的行。下面看看如何使用 XMLExists 来做这件事:

    删除居住在特定地区的客户的数据
delete from clients
where xmlexists('$c/Client/Address[zip="95116"]'
passing CUSTOMER.INFO as "c");
0
相关文章