“一往情深”通过精心收集,向本站投稿了8篇使用Lotus Notes数据库集成Amazon Web Service,以下是小编为大家整理后的使用Lotus Notes数据库集成Amazon Web Service,欢迎参阅,希望可以帮助到有需要的朋友。

篇1:使用Lotus Notes数据库集成Amazon Web Service
Amazon.com 的老用户可能会记得“Eyes”服务,这个服务可以让您设置自己感兴趣的产品的关键字列表,在出现与您所设置的关键字列表匹配的新产品时,就会向您发送一个电子邮件通知,其中包含这些新产品的链接,以及一些您可以在自己的 Web 站点上使用的服务的介绍,如果您是 Amazon 的会员,这会非常有用。随着使用这项服务的人数不断增加,Amazon.com 决定停止这项服务,因为它对处理器的需求非常高,并且难以维护。
之后,Amazon.com 提供了一项称为 Amazon Web Service 或 AWS 的 Web 服务,您可以使用它在自己的 Web 站点上查询 Amazon 的搜索引擎。这个 Web 服务允许我们创建一个与 Eyes 服务类似的应用程序。您可以将 Amazon Web Service 集成到一个 Notes 应用程序中,从而创建一个比 Eyes 更好的服务;集成方案提供了一种方法,通过这种方法,您可以使用自己的标准对书籍进行分类、标记不相关的书籍,以及在某本书籍停止出版时进行跟踪记录。这种技术目前被用来更新 Notes FAQ Web 站点 上的书籍清单。当然,也可以对 Amazon 上其他类型的产品清单使用这种技术。
本文共有两部分,在第 1 部分中,我们将简要介绍如何在一个 Notes 应用程序中集成 Amazon Web Service(AWS),从而可以使用 Notes Java API 查询 Amazon.com 的搜索引擎。我们还将介绍如何创建一个代理来删除对过期书籍的引用。在本文的第 2 部分中,我们将介绍如何使用 RDBMS 和 J2EE 技术重新创建这个应用程序。本文假设您具有开发 Notes 应用程序的经验,并且具有 Java 编程技巧。您可以从 Amazon.com 的 Web 站点上直接下载 Amazon 的 Web Services SDK。
SOAP 和 Web 服务
通过 Web 服务进行通信有很多方法,但是通常都使用以下两种方法:XML/HTTP 或者 SOAP(Simple Object Access Protocol)。XML/HTTP 方法使用了一种针对请求的专门格式化了的 URL。由于 XML/HTTP 访问方法使用一些编码后的参数来发起请求,因此它限制了 URL 的最大长度,这个长度大概是 1,024 个字符(有些服务器可以支持的长度更长,但是 1,024 个字符是一个比较安全的设置)。您所接收到的结果是使用 XML/SOAP 进行编码过的。您可以使用 XSLT 对 XML 进行转换,或者使用 XML 解析器从 XML 读取所需的值。然而,编写 XML 解析器的工作是非常繁琐的。
用来访问 Web 服务的 SOAP 技术利用了 Web 服务提供者所提供的 WSDL(Web Services Description Language)的定义。如果您要发布一个 Web 服务,就需要 WSDL 定义;通常可以通过一个 URL 来使用 Web 服务,这一点在本文后面部分将会看到。在这里,Amazon Web Service 提供了 WSDL 的定义。WSDL 定义描述了如何对请求进行格式化,以及如何读取响应信息,还将告诉您可以使用哪些请求。WSDL 是位于 Web 服务之上的另外一个复杂的层次,但是它真正提供的是生成“封装程序”来访问 Web 服务所需的桥梁,就仿佛这些服务在您自己的机器上一样。
可以使用以友好方式支持 Web 服务的任何语言生成调用 Web 服务的封装程序,这些语言包括 Java、C、VB、PHP、Perl、TCL,等等。另外,在“SOAP 请求”中发送的信息在大小方面存在限制,因为这些信息是在一个 Web 请求体中发送的,而不是在 URL 中发送的;这可以让您发出针对 Web 服务的复杂请求,因为在 Web 请求体中没有大小的限制。
Amazon Web Service
在 Amazon.com Web Service 页面 中,您可以看到更多有关 Amazon Web 服务的信息。您可以看到 SDK 中提供的 Java、Perl、PHP 和 VB 的示例代码。这个工具中还包括使用 SDK 的文档。这里还有一个开发人员论坛,Amazon 会对其进行监视。在可以调用 Amazon Web 服务的 API 之前,首先需要注册一个开发人员帐号。在 Amazon 的客户使用 Amazon Associate Web 站点来添加 Amazon 的订单记录时,可以使用这个开发人员帐号来提供 Amazon Associate 的推荐记录。如果您使用 Amazon 的 XSLT 服务将 XML 结果转换成 HTML 格式,那么该帐号将自动嵌入所返回的 URL 中,这样您就可以获得推荐费了。
Amazon 在自己的 Web 服务实现中提供了很多功能,这是可以使用 Web 服务来实现哪些功能的一个很好例证。它们不但提供了对搜索引擎的调用功能,而且还提供了管理 Amazon 用户的购物车、购买意向和邮购信息等级的功能。实际上,Web 服务的意图在于允许 Amazon Associate(他们支付推荐费)使用一种更加灵活的方法来构建 Web 店面(Web storefront),从而帮助销售更多的 Amazon 产品。这就是为什么它是一个很好的 Web 服务的例子:它可以帮助 Web 服务的提供者增加收益。
对于本文来说,我们感兴趣的内容是 Amazon 搜索引擎的 Web Services API。在开始之前,我们需要准备以下内容:
安装 Amazon Web Service。有关的更多信息,请参阅 Amazon Web 服务的 SDK 中的文档。
为了进行测试,我们创建一个 Notes 应用程序来使用 AWS。
要使用 Amazon 搜索引擎,您必须在 Notes 应用程序中指定的第一项内容是称为模式的东西;这等同于您在 Amazon.com 主页上可以看到的高级附签:书籍、音乐、工具,等等。然后您就可以根据以下内容进行搜索:关键字、浏览节点(产品目录,例如如果将模式设置为书籍,就可以查找科幻小说)、ASIN、ISBM、UPC、作者、音乐家、演员、导演、发行商、ListMania! 和类似产品(顾客可能购买的其他产品)。对于我们正在构建的 BetterEyes 服务来说,我们将使用关键字进行搜索。
Notes/Domino 6 中对 XML 的支持
Notes/Domino 6 包含了对 XML 的支持,这与 Notes/Domino R5 不同,后者需要添加一个工具包才能支持 XML。我们将来了解一下如何使用 Notes 的 XML 支持来构建 BetterEyes 服务,然后再来了解一下为什么应该使用 SOAP。在 Amazon 的 Web 服务中有一个 XML/HTTP 的例子,请使用 Internet Explorer 5.5 或更高的版本来查看 这个 URL 的内容。
您会看到一个经过很好的格式化的 XML 结果,然后可以单击 + 和 - 符号来展开或收缩层次结构。
图 1. Amazon.com 中的 XML 例子
使用 Notes/Domino 5 或 Notes/Domino 6,就可以使用 Personal Web Navigator 来查询 Amazon.com 的内容,下面是 Notes LotusScript. 引擎中的一段代码:
Dim filename as Stringfilename$ = “c:\temp\amazon.xml”Dim NURLdb As New NotesDatabase(“”,“”)' To reference the Internet browser databaseDim Nwebdoc As NotesDocumentIf NURLdb.OpenURLDb ThenDim filename As String' download the XML encoded WS replyIf (False) ThentheURL = “xml.amazon.com/onca/xml?v=2.0&dev-t=webservices-20&t=thelotusnotesfaqA&KeywordSearch=Lotus+Notes&mode=books&type=lite&page=1&f=xml”Set Nwebdoc=NURLdb.getdocumentbyurl(theUrl, True, False)' get XML from attachmentDim Item As NotesItemDim Object As NotesEmbeddedObjectSet Item = Nwebdoc.GetFirstItem(“$FILE”)Dim ItemName As StringItemName = Item.Values(0)Set bject = Nwebdoc.GetAttachment(ItemName)Call Object.ExtractFile(filename$)End IfEnd If当 Amazon 发回 XML 响应时,将其作为一个附件保存在 Personal Web Navigator 数据库中。需要将附件的内容保存到文件系统中,这样就可以从响应中处理 XML 的内容了。Notes/Domino 6 有两个内嵌的 XML 解析器:SAX 和 DOM。SAX 解析器使用的内存更少,因为它是一个回调风格的 API,因此它不需要将整个 XML 文档都保存在内存中。DOM 解析器更易于使用,因此我们将着重使用 DOM。有关 SAX 和 DOM 解析器的更多内容,请参阅 LDD Today 撰写的文章“LotusScript. XML classes in Notes/Domino 6”。
下面的代码将输出从 Amazon Web 服务查询中返回的 XML 结果:
' open XML file as a streamDim xml_in As NotesStreamSet xml_in=session.CreateStreamIf xml_in.Open(filename$) ThenIf xml_in.Bytes = 0 ThenMessagebox filename$ + “ is empty”End If' create a temporary output file because it's not a pipelined XML operationDim xml_out As NotesStreamDim outfilename as Stringoutfilename$ = “c:\temp\amazon.tmp” ' create output fileSet xml_out=session.CreateStreamIf Not xml_out.Open(outfilename$) ThenMessagebox “Cannot create ” & outfilename$,, “TXT file error”Exit SubEnd Ifxml_out.Truncate' parse using DOM parserSet domParser=session.CreateDOMParser(xml_in, xml_out)On Error Goto DumpDOMLogDOMParser.ExitOnFirstFatalError = TrueDOMParser.InputValidationOption = 0' disable validation of problematic Amazon XML resultsdomParser.ProcessOn Error Goto 0Dim docNode As NotesDOMDocumentNodeSet docNode = domParser.Document' last child at root is ProductInfoDim productinfoNode As NotesDOMNodeSet productinfoNode = docNode.LastChild' iterate through all the Details childrenDim detailsNode As NotesDOMNodeSet detailsNode = productinfoNode.FirstChildWhile (Not detailsNode.IsNull)Dim productname As StringDim publisher As Stringproductname = “”Dim infoNode As NotesDOMNodeSet infoNode = detailsNode.FirstChildWhile (Not infoNode.IsNull)If (infoNode.NodeName = “ProductName”) Thenproductname = infoNode.FirstChild.NodeValueElseif (infoNode.NodeName = “Manufacturer”) Thenpublisher = infoNode.FirstChild.NodeValueEnd IfSet infoNode = infoNode.NextSiblingWendIf (productname “”) ThenMessagebox “Found ” + productname+ “ from ” + publisherEnd IfSet detailsNode = detailsNode.NextSiblingWendEnd IfExit SubDumpDOMLog:Msgbox “DOMParser error: ” & DOMParser.logExit Sub正如您可以看到的,这段代码非常复杂,它创建了一些代码来遍历 XML 文档,从而检索所需要的信息。XML 输入验证被关闭,因为 Amazon 的 XML 响应存在问题,在 DOMParser 的错误记录中,该问题表现为一个无效的 URL;关闭这个有效性验证在处理很多 XML 时是必需的,因为可能会错误地生成 XML。另外,还需要对 XML 模式有足够的了解,知道自己希望了解哪些级别的信息。在上面这个例子中,作者信息位于一个级别较低的节点上。您还需要了解这些节点是如何命名的,并且需要正确拼写它们(如果拼写错误,就不能进行什么错误检查了)。
在下一节中,我们将介绍 SOAP 封装程序是如何对此进行简化,并以更加直观和更加安全的方式表现它们。
Axis SOAP 封装程序
正如前面所介绍的,大部分语言都有一个 SOAP 封装程序生成器。这些生成器使用一个 WSDL 描述并生成一个封装对象,这样就可以使用 Web 服务,就像它是语言的一部分那样。单击这里 查看 Amazon 的 Web Service WSDL 描述的内容。这是最新版本的 Amazon Web Service WSDL 描述。您可以将其保存为一个文本文件 AmazonWebServices.wsdl。
在 Java 中,实际的 SOAP 封装程序来自 Apache Web 服务器项目。该项目的名称为 Axis,您可以从 Apache Axis Web 站点 上下载它。Axis 在很多工具中以各种形式得到了广泛的应用,这些工具中包括 IBM 的 Web Services Toolkit 和 Borland 的 JBuilder。尽管我们只是要使用它来生成一个 SOAP 封装程序与一个 Web 服务进行通信,但是这也需要生成封装程序,这样您就可以作为 Web 服务来提供一些 Java 类了。
在下载 Axis 之后,请按照 Web 站点上的提示来安装它。完成安装 Axis 之后,就可以使用下面以下命令行告诉 Axis 为 Amazon Web 服务生成封装类了:
java java org.apache.axis.wsdl.WSDL2Java AmazonWebServices.wsdl--output build/axis --verbose --package com.amazon.soap.axis这个命令将生成一些 Java 文件,它们将编译到 com.amazon.soap.axis Java 包中。下面是生成 ProductInfo XML 节点使用的代码:
/*** ProductInfo.java** This file was auto-generated from WSDL* by the Apache Axis WSDL2Java emitter.*/package com.amazon.soap.axis;public class ProductInfo implements java.io.Serializable {private java.lang.String totalResults;private java.lang.String listName;private com.amazon.soap.axis.Details[] details;public ProductInfo {}public java.lang.String getTotalResults() {return totalResults;}public void setTotalResults(java.lang.String totalResults) {this.totalResults = totalResults;}public java.lang.String getListName() {return listName;}public void setListName(java.lang.String listName) {this.listName = listName;}public com.amazon.soap.axis.Details[] getDetails() {return details;}public void setDetails(com.amazon.soap.axis.Details[] details) {this.details = details;}private java.lang.Object __equalsCalc = null;public synchronized boolean equals(java.lang.Object obj) {if (!(obj instanceof ProductInfo)) return false;ProductInfo ther = (ProductInfo) obj;if (obj == null) return false;if (this == obj) return true;if (__equalsCalc != null) {return (__equalsCalc == obj);}__equalsCalc = obj;boolean _equals;_equals = true &&((totalResults==null &&other.getTotalResults()==null) ||(totalResults!=null &&totalResults.equals(other.getTotalResults()))) &&((listName==null && other.getListName()==null) ||(listName!=null &&listName.equals(other.getListName()))) &&((details==null && other.getDetails()==null) ||(details!=null &&java.util.Arrays.equals(details, other.getDetails())));__equalsCalc = null;return _equals;}private boolean __hashCodeCalc = false;public synchronized int hashCode() {if (__hashCodeCalc) {return 0;}__hashCodeCalc = true;int _hashCode = 1;if (getTotalResults() != null) {_hashCode += getTotalResults().hashCode();}if (getListName() != null) {_hashCode += getListName().hashCode();}if (getDetails() != null) {for (int i=0;ii++) {
java.lang.Object obj
= java.lang.reflect.Array.get(getDetails(), i);
if (obj != null &&
!obj.getClass().isArray()) {
_hashCode += obj.hashCode();
}
}
}
__hashCodeCalc = false;
return _hashCode;
}
// Type metadata
private static org.apache.axis.description.TypeDesc typeDesc =
new org.apache.axis.description.TypeDesc(ProductInfo.class);
static {
org.apache.axis.description.FieldDesc field
= new org.apache.axis.description.ElementDesc();
field.setFieldName(“totalResults”);
field.setXmlName(new javax.xml.namespace.QName(“”, “TotalResults”));
field.setXmlType(new javax.xml.namespace.QName
(“ www.w3.org//XMLSchema ”, “string”));
typeDesc.addFieldDesc(field);
field = new org.apache.axis.description.ElementDesc();
field.setFieldName(“listName”);
field.setXmlName(new javax.xml.namespace.QName(“”, “ListName”));
field.setXmlType(new javax.xml.namespace.QName
(“ www.w3.org/2001/XMLSchema ”, “string”));
typeDesc.addFieldDesc(field);
field = new org.apache.axis.description.ElementDesc();
field.setFieldName(“details”);
field.setXmlName(new javax.xml.namespace.QName(“”, “Details”));
field.setXmlType(new javax.xml.namespace.QName
(“urn:PI/DevCentral/SoapService”, “DetailsArray”));
typeDesc.addFieldDesc(field);
};
/**
* Return type metadata object
*/
public static org.apache.axis.description.TypeDesc getTypeDesc() {
return typeDesc;
}
/**
* Get Custom Serializer
*/
public static org.apache.axis.encoding.Serializer getSerializer(
java.lang.String mechType,
java.lang.Class _javaType,
javax.xml.namespace.QName _xmlType) {
return
new org.apache.axis.encoding.ser.BeanSerializer(
_javaType, _xmlType, typeDesc);
}
/**
* Get Custom Deserializer
*/
public static org.apache.axis.encoding.Deserializer getDeserializer(
java.lang.String mechType,
java.lang.Class _javaType,
javax.xml.namespace.QName _xmlType) {
return
new org.apache.axis.encoding.ser.BeanDeserializer(
_javaType, _xmlType, typeDesc);
}
}
这段代码看起来非常复杂,但是它的基本功能是允许简单地访问 XML 的结果,实现这一点的方法是将 XML ProductInfo 节点的属性当作 Java String 对象看待,将下面的 XML 节点当作 Java 数组对象看待,
封装程序还要使这些对象“连续”,这样您就可以将 XML 节点通过网络转换成一个 Java 程序,或者将 XML 节点保存到文件中。
在生成封装类之后,您就可以创建一个简单的程序来调用 Amazon Web Service。将以下代码保存到 AmazonUpdate.java 文件中:
import com.amazon.soap.axis.*;public class AmazonUpdate{public static void main(String[] args) throws Exception{AmazonSearchService service = new AmazonSearchServiceLocator();AmazonSearchPort port = service.getAmazonSearchPort();KeywordRequest request = new KeywordRequest();request.setKeyword(java.net.URLEncoder.encode(“Lotus Notes”));request.setMode(“books”);request.setTag(“”);request.setType(“lite”);request.setDevtag(“”);request.setPage(“1”);ProductInfo result = null;try {result = port.keywordSearchRequest(request);} catch (Exception e) {e.printStackTrace();}Details[] details = result.getDetails();for (int i = 0; i < details.length; i++) {// read results outString resultTitle = details[i].getProductName();System.out.println(“Title #” + i + “ is ” + resultTitle);}}}现在您可以使用下面的命令来编译这个程序和 SOAP 封装程序了:
javac AmazonUpdate.java build/axis/com/amazon/soap/axis/*.java使用下面的命令来运行这个程序:
java -classpath build/axis/com/amazon/soap/axis;%CLASSPATH% AmazonUpdate它会输出第一个结果页面中的书籍的标题。注意,您并不需要了解太多有关 Amazon Web 服务的内容,甚至不需要指定 URL 来访问 Amazon Web Service,因为这些信息都内嵌在 WSDL 文件中的。您还要进行 Java 的类型/方法检查,确保没有错误地调用 Amazon Web Services API,也没有使用错误的数据类型对结果进行解释。
AmazonUpdate Java 程序
现在我们已经有一个可以调用 Amazon Web 服务的基本框架了,接下来就可以开发所需要的完整应用程序了。不幸的是,在 Amazon 的 Web Services API 中有一个 bug:所返回的结果总数并不正确。每个 Web 服务调用最多可以返回 10 个结果。我们需要使用一个循环进行遍历,直到所返回的结果少于 10 个或出现错误为止。循环体如下所示:
boolean fKeepgoing = true;int realcount = 0;int page = 0;do {page++;request.setPage(“” + page);ProductInfo result = null;try {result = port.keywordSearchRequest(request);} catch (Exception e) {org.apache.axis.AxisFault afe = null;if (e instanceof org.apache.axis.AxisFault) {afe = (org.apache.axis.AxisFault) e;}if ((afe == null) || (afe.getFaultString().indexOf(“Bad Request”) < 0)) {// Amazon's results “end” when the page you request gets a requesterror or if less than 10 results are returnede.printStackTrace();}fKeepgoing = false;break;}Details[] details = result.getDetails();for (int i = 0; i < details.length; i++) {// values that will be passed to trackerString resultTitle = null;String resultISBN = null;String resultASIN = null;String resultAuthors = null;String resultPublisher = null;// read results outresultTitle = details[i].getProductName();resultASIN = details[i].getAsin();if (details[i].getIsbn() != null) {resultISBN = details[i].getIsbn();
}String authors[] = details[i].getAuthors();String authorlist = “”;if (authors != null) {for (int j = 0; j < authors.length; j++) {if (j >0) {authorlist += “, ”;}authorlist += authors[j];}}resultAuthors = authorlist;if (details[i].getManufacturer() != null) {resultPublisher = details[i].getManufacturer();}// give results to trackertracker.updateBook(resultTitle,resultASIN,resultISBN,resultAuthors,resultPublisher);// increment result counterrealcount++;}if (details.length < 10) {fKeepgoing = false;}} while (fKeepgoing);BookUpdate 接口
您可能会纳闷 tracker.updateBook() 调用到底是用来干什么用的。它是一个 Java 接口调用,使用它可以更新我们要跟踪的书籍的数据库。通过将其声明为一个接口,可以使用不同的类来获取这些信息,这样就可以对应用程序进行调试,或者将信息写入一个 Notes 数据库、关系型数据库或其他数据存储器中。
public interface BookTracker{public void updateBook(String title, String ASIN, String ISBN,String authors, String publisher, String rating, int numreviews)throws Exception;}调试初步:将调试信息输出到标准输出设备上
正如您猜想的那样,调试类非常简单,因为它所做的工作不过是向标准输出设备输出一些信息,这些信息就是运行 Java 应用程序时在命令窗口中显示的信息。这个类如下所示:
public class DumpBookTracker implements BookTracker {// update book from amazon querypublic void updateBook(String title,String ASIN,String ISBN,String authors,String publisher) {System.out.println(title);System.out.println(“; ASIN: ” + ASIN);if (ISBN != null) {System.out.println(“; ISBN: ” + ISBN);}if (publisher != null) {System.out.println(“; Publisher: ” + publisher);}if (authors != null) {System.out.println(“; Authors: ” + authors);}}}与 Notes 进行集成:表单和视图
现在就可以创建一个 Notes 表单来显示这些信息了:
图 2. Notes 表单
前 5 行的内容分别是标题、作者、出版商、ISBN 和 ASIN,其中包含保存在 BookTracker 接口中的信息。State 字段允许我们将这本书标记成已经不再出版或不再具有相关性(例如,突然发现有一本书是与 Notes/Domino 无关的)。Notes Version 字段可以判断这本书所使用的 Notes 的版本。Category 字段可以确定该书属于哪一类:管理类的、编程类的,等等。
您还需要两个 Notes 视图。一个视图名为 LUBookASIN。第一个(也是惟一一个)排序列中包含 ASIN 字段。ASIN 是 Amazon 为每种产品分配唯一 ID。对于电子书籍来说,ISBM 可以为空。隐藏的 lookup 视图可以用来更新书籍的状态,这样我们就可以知道一本书何时最后一次出现在 Amazon 的 Web 站点上;如果某一本书不再能通过关键字进行查询,那么将无法发布这本书,因为在 Amazon 的搜索引擎中,不会返回不再出版的书籍。如果可以使用一个关键字搜索到某一本书籍,但通过查阅数据块中的 ASIN 却无法查到这本书,那么这本书是一本新书,需要将它添加到数据库中。
第二个视图称为 Books\by Status。这个视图中的第一个分类列是 Status 字段。第二列是 Notes Version 字段。第三列是 Title 字段。您可以使用这个视图来管理 AmazonUpdate 程序可以添加的书籍。
将新书保存到 Notes 数据库中
现在我们有地方来存放 Java 应用程序找到的每本书了,接下来可以编写一个 BookTracker 类,该类知道如何将这些书籍保存到 Notes 数据库中。它比那个调试类稍微复杂一些,但也不是很复杂。它使用 Notes Java API,因此您需要在自己的 classpath 中包含 notes.jar 文件(在 notes.exe 所在的 Notes 目录中):
import lotus.domino.*;public class NotesBookTracker implements BookTracker {lotus.domino.Session s;Database db;View booksview;// constructorpublic NotesBookTracker(String server, String dbname)NotesException {// initialize Notes accessNotesThread.sinitThread();s = NotesFactory.createSession();// get book ISBN viewdb = s.getDatabase(server, dbname);booksview = db.getView(“(LUBookASIN)”);}// Java pseudo-destructorpublic void finalize() throws NotesException {// clean up NotesNotesThread.stermThread();}// update book from amazon querypublic void updateBook(String title,String ASIN,String ISBN,String authors,String publisher)throws NotesException {// check for blank ISBNif (ISBN == null) {System.out.println(title + “ has a null ISBN!”);}// check for blank ASINif (ASIN == null) {System.out.println(title + “ has a null ASIN!”);}Document doc;// see if we can find the bookdoc = booksview.getDocumentByKey(ASIN, true);if (doc == null) {// new book, so we have to add it to the databasedoc = db.createDocument();doc.replaceItemValue(“Form”, “Book”);doc.replaceItemValue(“Title”, title);doc.replaceItemValue(“ASIN”, ASIN);if (ISBN != null) { // E-books don't have an ISBNdoc.replaceItemValue(“ISBN”, ISBN);}if (authors != null) {doc.replaceItemValue(“Authors”, authors);}if (publisher != null) {doc.replaceItemValue(“Publisher”, publisher);}doc.replaceItemValue(“State”, “Added”);}// tag it w/ timestamp so we know when it was last found// so we can expire unfound books in a scheduled agentDateTime timenow = s.createDateTime(“Today”);timenow.setNow();doc.replaceItemValue(“LastFound”, timenow);// save documentdoc.save();}}编辑表单并查看书籍
在从 Amazon.com 上接收到信息之后,接下来需要在 Notes 数据库中编辑 State、Notes Version 和 Categories 字段的内容。下图显示了一个处于编辑模式的文档。
图 3. Notes 文档
在编辑了 Java 代理所发现的新书的字段之后,就应该有一个非常有用的视图了,如下所示:
图 4. Book 视图
将书籍标记为不再出版
这是我们的 BetterEyes 应用程序比 Amazon 的 Eyes 服务多做的一件事。当有些书籍不再出版时,Eyes 服务并不会通知您。Amazon 为 Amazon Associates 提供了另外一个特性,它可以让您了解 Web 站点的访问者何时引用了那些已经不再可用产品的链接;然后您应该手工编辑这些链接。
在 Notes 中,可以创建一个调度代理,将一些书籍标记为不再出版。您会注意到,每次运行 AmazonUpdate 应用程序时,都会对现有的文档进行更新,并存储一个 LastFound 日期。然后,我们可以创建一个调度代理,它每 30 天运行一次以下文档:
图 5. 调度代理
并执行这个简单操作:
图 6. 调度代理:简单操作
以上就是这个代理要执行的所有操作。我们现在可以创建一个视图来显示目前可以订购的书籍,这可以通过检查 State 字段的值并确定它不是 No Longer Published 来实现。
用作 Notes/Domino 6 Java 代理的 AmazonUpdate
将 AmazonUpdate Java 应用程序转换为一个 Notes/Domino 6 Java 代理非常简单。但不能在 R5 中这样做,因为 R5 使用的是 Java Runtime 1.1.8,而 Notes/Domino 6 使用的是 JRE 1.3.1。您需要做的第一件事情就是将这些 JAR 文件添加到 Notes 和 Domino 的类路径中。
在 Notes/Domino 6 和 Notes/Domino R5 中,对 Java 类路径的处理有所不同,因为 Notes/Domino 6 使用的是更加新的 JVM。在 Notes 或 Domino 目录中,有一个 JVM 子目录,其中保存了 JVM 二进制文件和 JAR 文件。如果您希望将 JAR 文件添加到代理的类路径中,那么可以将其添加到 jvm\lib\ext 目录中。您应该将 axis.jar、jaxrpc.jar、saaj.jar、commons-logging.jar、commons-discovery.jar 添加到这个目录中(请参阅 Axis 文档,了解到底需要哪些文件,因为在发布时, JAR 文件可能会发生变化)。
AmazonUpdate.jar 文件也应该被添加到 jvm\lib\ext 目录中。JAR 文件中包括我们为这个应用程序创建的所有 CLASS 文件和 SOAP 代理类。通过转至存放应用程序的目录(上面假设在 c:\AmazonUpdate 目录)中并输入下面的命令,可以创建这个 JAR 文件:
jar -cvf AmazonUpdate.jar *.class com\amazon\soap\axis\*.classcd build\axisjar -cvf ..\..\AmazonUpdate.jar com\amazon\soap\axis\*.class我们之所以这样做,而不是将所有的 JAVA 文件都导入 IDE,是因为如果您试图在 Domino Designer 中导入很多 JAVA 文件,那么 Domino Designer 的速度就会明显减慢,因为它试图确定要展开/收缩显示哪些代码。将不会发生变化的代码放入一个 JAR 文件,并将其放到类路径中,这样会加快速度。
另外,您还需要在路径中添加一个 SAX API 兼容的 XML 解析器。最简单的 XML 解析器就是 Apache 的 Crimson 解析器,它来自 crimson.jar 中的一个表单。不幸的是,不能将其添加到 jvm\lib\ext 目录中,因为 Notes/Domino 6 在 Notes 可执行目录的 xml4j.jar 中有自己的 DOM 解析器。幸运的是,我们可以通过使用 JavaUserClasses Notes.ini 变量,将自己的类放到包含 xml4j.jar 文件的搜索路径的前面。请将下面这行代码添加到 Notes.ini 文件中(假设这个文件位于 C:\JARs 目录中):
JavaUserClasses=c:\JARs\crimson.jar注意您在 JavaUserClasses 变量中放入了多少路径。对于所有 Notes.ini 变量而言,每个变量的最大长度都是 255 个字符。这个限制很容易被突破,因为所有有用的 Java JAR 文件都可以在此列出。惟一的解决方案就是将它们放在位于某个驱动的根目录上的只有一个字符的目录名中,但是,如果不断添加 JAR 文件,那么这种方法也不能解决多少问题。
在完成这种设置之后,就可以在 Domino Designer 中创建一个 Java 代理了。您所需要的只是以下几行代码:
import lotus.domino.*;public class JavaAgent extends AgentBase {public void NotesMail() {try {Session session = getSession();AgentContext agentContext = session.getAgentContext();BookTracker tracker = new DumpBookTracker();//BookTracker tracker = new NotesBookTracker(“SlipGate”,“Notes”)AmazonUpdate.getAmazonBooks(“lotus domino”, tracker);AmazonUpdate.getAmazonBooks(“lotus notes”, tracker);} catch(Exception e) {e.printStackTrace();}}}我们再次使用 DumpBookTracker API 进行测试。将这个代理设置为手工从菜单中运行,这样就可以在 Notes 客户机中进行测试了:
图 7. Agent Properties 对话框
在运行这个代理之前,请在 Notes 客户端中选择 File - Tools - ShowJavaConsole,这样就可以看到在 BookTracker 类中调用 System.out.println 时的所有输出。来自 Java 虚拟机中的错误消息,包括有关不能找到某些类的错误消息,都会显示在这个窗口中。
结束语
我们已经创建了一个使用 Amazon Web Service 的非常有用的 Java 应用程序。开源的 Axis SOAP 代理生成器将这个任务变得太过简单,因为它看起来就像是我们正在使用一些普通的 Java 类;只要这个 Web 服务提供一个 WSDL 文件,就无需要担心如何访问这个 Web 服务,也无需要担心如何与之进行交谈。
通过将来自 Amazon Web Service 的信息保存到一个 Note 数据库中,可以构建一个比 Amazon 以前的 Eyes 服务更有用的程序,因为我们既可以添加新书,也可以跟踪那些已经不再出版的书籍。此外,可以将这个 Notes 数据库放到 Domino 服务器上,通过 Web 对其进行访问。所有的 Notes 工作都可以在几个小时内完成,而且为 Amazon 通过 Amazon Web 服务提供的许多有用信息提供了一个接口。
在下一篇文章中,我们将使用 DB2 和 JSP(JavaServer Page)来重新构建一个类似的应用程序。然后,我们将使用 EJB 和一些自动化工具(MiddleGen、XDoclet 和 Ant)来重新构建这个应用程序,使用这些工具,可以降低 EJB 使用的繁琐程度。
篇2:《使用数据库》说课稿
《使用数据库》说课稿
各位评委,各位老师:
大家好!我说课的题目是:《使用数据库》。主要分为四个方面来说课,分别是说教材、说学生、说教法、说教学过程。
一、说教材
⑴本节作用和地位:数据库管理是指应用数据库技术对信息资源进行管理,通过开发相应的数据库应用系统,实现某类信息资源的组织、存储和管理,提供录入、查询、修改、删除、统计和打印等功能,帮助人们完成计划、组织、控制、决策等系统活动。
⑵本节第一部分,教材中共设置了3个任务:一是学生自主选择一个数据库应用系统,了解数据库应用系统的主要功能和特点;二是使用和分析搜索引擎,了解其在管理大量数据与检索信息方面的优势;三是使用在线数据库应用系统检索信息,对查询的资料进行统计和分析,并对资料的准确性、丰富性和权威性等进行评价和讨论。
第二部分,使用数据库管理信息的优势。主要阐述信息资源管理的基本工作过程和使用数据库应用系统的优势。
二、说学情:本节内容对学生可以说陌生,但又有感性认识,因为学生在日常生活中对会计做账,聊天,网络游戏有些认识,但他们对数据库的基本工作原理及功能知之甚少,缺乏了解。因此,教学中,课前出除了要吃透教材之外,还要准备相关的资料,供学生开阔视野之用。
三、说教学策略
任务1的目的是让学生对数据库存储、管理大量数据并实现高效检索方面的优势有一个新的认识。因此我选择一个具体的学籍管理信息系统进行分析,目的是让学生了解系统的主要功能及特点,
任务2中,对于搜索引擎使用的分析与评价,应于第二章第二节有区别,李节是引导学生了解搜索引擎是如何组织和管理信息的,它的信息是如何添加并为使用者提供检索的等等。
任务3中老师可以有一些自由度了,可以让学生上在线数据库,注册、登陆进行信息检索。
学习目标:通过使用常见的数据库应用系统,感受到用数据库存储、管理大量数据并实现高效检索的优势。
学习重难点:认识到数据库存储、管理数据及高效检索的优势。
学习方法:讲解+练习。
四、说教学过程
(第一课时)
⑴课堂活动
为了方便同学们的沟通,我们需要有一个通讯录。通讯录的制作方法有很多种,我们可以用一个小笔记本来作通讯录,把同学们的通讯电话和地址都登记下来,这里我们也可以使用数据库来作通讯录(如同学们建的班级QQ群,实质是一个通讯录),同学们比较一下,使用数据库管理通讯录和使用笔记本管理通讯录各自的特点是什么,哪一个更优胜?使用数据库管理与使用手工管理同学信息的比较分析。
在众多的信息资源管理方法种,数据库(Database)及其管理、应用系统是目前信息资源管理的一种有效方法。他们在信息的收集、存储、加工、管理等方面,为人们提供方便、快捷和高效的服务,以帮助人们进行计划、组织、控制,决策等一系列的活动。
⑵课堂活动:使用数据库应用系统
前面的通讯录数据库只是一个很简单的数据库而已,下面我们看看一些比较完整的数据库应用系统,分析一下他们的功能和特点。
◎学生学籍信息管理系统
数据库应用系统一般所具有的功能有:录入、查找、修改、删除、统计等操作。(见下图)
通过实际操作以及查阅系统的使用说明,填写下表:
数据库应用系统名称
存储信息的具体项目
存储信息的总量
系统包含的操作 □添加 □修改 □删除 □插入 □统计 □打印 □检索
操作的共享性 □单机上使用 □网络上独占使用 □网络上共享使用
检索的效率 □迅速得出结果 □检索结果准确
维护的方便性 □备份 □重组 □安全
在众多的信息资源管理方法种,数据库(Database)及其管理、应用系统是目前信息资源管理的一种有效方法。他们在信息的收集、存储、加工、管理等方面,为人们提供方便、快捷和高效的服务,以帮助人们进行计划、组织、控制,决策等一系列的.活动。
数据库应用系统在网络上也有很广泛的应用,如网上搜索引擎就是一种由大量数据信息组成的大型数据库。当用户输入关键词之后,系统从数据库中筛选出符合条件的内容。
同学们可以使用和分析搜索引擎,了解搜索引擎在管理大量数据及其高效检索信息方面的优势。
搜索引擎基本工作原理(小结)
全文搜索引擎
在搜索引擎分类部分我们提到过全文搜索引擎从网站提取信息建立网页数据库的概念。搜索引擎的自动信息搜集功能分两种。一种是定期搜索,即每隔一段时间(比如Google一般是28天),搜索引擎主动派出“蜘蛛”程序,对一定IP地址范围内的互联网站进行检索,一旦发现新的网站,它会自动提取网站的信息和网址加入自己的数据库。
另一种是提交网站搜索,即网站拥有者主动向搜索引擎提交网址,它在一定时间内(2天到数月不等)定向向你的网站派出“蜘蛛”程序,扫描你的网站并将有关信息存入数据库,以备用户查询。由于近年来搜索引擎索引规则发生了很大变化,主动提交网址并不保证你的网站能进入搜索引擎数据库,因此目前最好的办法是多获得一些外部链接,让搜索引擎有更多机会找到你并自动将你的网站收录。
当用户以关键词查找信息时,搜索引擎会在数据库中进行搜寻,如果找到与用户要求内容相符的网站,便采用特殊的算法——通常根据网页中关键词的匹配程度,出现的位置/频次,链接质量等——计算出各网页的相关度及排名等级,然后根据关联度高低,按顺序将这些网页链接返回给用户。
目录索引
搜索引擎中各网站的有关信息都是从用户网页中自动提取的,所以用户的角度看,我们拥有更多的自主权;而目录索引则要求必须手工另外填写网站信息,而且还有各种各样的限制。更有甚者,如果工作人员认为你提交网站的目录、网站信息不合适,他可以随时对其进行调整,当然事先是不会和你商量的。
目录索引,顾名思义就是将网站分门别类地存放在相应的目录中,因此用户在查询信息时,可选择关键词搜索,也可按分类目录逐层查找。如以关键词搜索,返回的结果跟搜索引擎一样,也是根据信息关联程度排列网站,只不过其中人为因素要多一些。如果按分层目录查找,某一目录中网站的排名则是由标题字母的先后顺序决定(也有例外)。
(第二课时)
⑶课堂活动3:数据库库
另外在一些专业领域,还提供了一些在线数据库,在线数据库是指以网站形式提供服务,可以远程查询的一类书库,同学们也可以自行使用在线数据库系统检索信息,了解在线数据库管理信息及其检索信息的优势。
(第二课时)(三)使用数据库管理信息的优势
从上面的活动中,我们对使用数据库存储和管理信息资源有了比较清晰的认识,对使用数据库应用系统实现高效检索有了切身的体会。
1、信息资源管理的基本工作过程主要包括下面几个方面
(1)组织和存储信息,即将收集到的信息按内容或载体进行合理的分类组织,将其存储在物理介质上,使信息能够被长期地保存下来。
(2)维护和备份信息,即根据需要随时进行增加、修改和删除信息等操作,同时要注意定期备份保存信息,以便出现安全问题的时候能够及时恢复,防止不必要的损失。
(3)提供信息查询和统计功能,以便快捷、准确地将获取需要的信息,满足各种使用要求。我们还可以根据自己的实际需要,利用各种搜索工具(包括信息系统的搜索功能、搜索引擎或者智能搜索工具等)来选择恰当的搜索策略和提高搜索技巧,并经过统计分析后得到所需要的信息或产生新的知识。
(4)开发新的信息资源。经过分类和整理之后,我们还可以对信息进行新的组合或提炼,包括对信息的综合、比较、分析、研究等系列操作,开发出更为宝贵的信息资源,发挥信息资源的价值,形成新的知识或创造更大的效益。
2、使用数据库应用系统的优势主要包括下面几个方面
(1)能够存储大量数据,且占用空间少。
(2)管理操作方便、快捷,数据维护简单、安全。使用数据库管理信息资源,可以进行添加、修改、插入、删除等操作,而且使用方便、快捷。
(3)检索统计准确、迅速、高效。
(4)数据应用共享性能好。
正是由于数据库影院系统在存储、管理和检索信息方面存在如此巨大的优势,它们在社会各个领域中得到了广泛的应用并产生了深远的影响。因此,熟练运用这些系统的基本操作方法和使用技巧,从中掌握科学评价和恰当选择系统的方法,应当成为我们每个人具备的生活技能。
篇3:SQLServer和XML的集成数据库
XML可谓最新的数据存储 解决方案 了,XML相比HTML给予了Web 开发 人员更大的编程灵活性。这种新技术驱动开发机构尝试把XML同自己的产品集成起来。微软就是采取如此举措的先驱者。微软公司在开发Inte .net 产品的时候一度慢慢腾腾,现在可就不同了。 最近一位
XML可谓最新的数据存储解决方案了。XML相比HTML给予了Web开发人员更大的编程灵活性。这种新技术驱动开发机构尝试把XML同自己的产品集成起来。微软就是采取如此举措的先驱者。微软公司在开发Inte.net产品的时候一度慢慢腾腾,现在可就不同了。最近一位微软公司的高级职员就这样说:“你要给我们一刀,伤口里出来的尽是XML。”也许形容得有点过分,但事实确实是这样的:微软的几乎所有产品中都能看到XML的身影。举个例子:微软是如何在其SQL Server产品线中集成XML的呢?下面咱们就来看看关键的FOR XML子句。
以XML的名义获取信息
SQL Server和XML之间的集成首要一点就是根据SQL数据创建XML文件。XML文件的构造并不复杂,用简单的脚本和ADO记录集就可以轻松产生。这个任务虽然不算麻烦,但开发人员却需要针对他们从服务器获取的结果集合产生不同的脚本,或者编写更为复杂的通用脚本。SELECT 语句则由此而配备了新的FOR XML子句。
该子句的语法如下所示:
[ FOR { XML { RAW | AUTO | EXPLICIT }
[ , XMLDATA ]
[ , ELEMENTS ]
[ , BINARY BASE64 ] } ]
FOR XML子句的XML模式由三种参数值表示:RAW、AUTO或者EXPLICIT。模式决定了结果XML的形式和组成。下面我们就更深入些地通过以下示例了解以上各个XML选项。
RAW示例
我们执行以下的SQL语句:
SET ROWCOUNT 3
SELECT Orders.OrderID, Orders.OrderDate, ProductID
FROM Orders, [Order Details]
WHERE Orders.OrderID = [Order Details].OrderID
ORDER BY Orders.OrderID
FOR XML RAW
执行后产生的结果如下:
AUTO示例
我们执行以下的SQL语句:
‘结果限制为3条记录。
SET ROWCOUNT 3
SELECT Orders.OrderID, Orders.OrderDate, ProductID
FROM Orders, [Order Details]
WHERE Orders.OrderID = [Order Details].OrderID
ORDER BY Orders.OrderID
FOR XML AUTO
产生的结果如下所示:
EXPLICIT示例
Explicit模式给予查询编程人员对产生XML的完全控制能力,
然而这种控制力度却要价不菲:你得编写每一查询以便SQL语句能包含XML信息。
有关的语法很复杂,而且超出了本文的讨论范围。[ , XMLDATA ] [ , ELEMENTS ] [ , BINARY BASE64 ] 是相应的可选参数。
可选元素
示例可以让我们对各种设置的内部工作机理有更多的了解,下面我们就进一步研究下FOR XML语句的可选元素XMLDATA。
如果你设置该选项,那么XML-Data schema就会包含在结果集合里。以下是SQL语句:
SET ROWCOUNT 3
SELECT Orders.OrderID, Orders.OrderDate, ProductID
FROM Orders, [Order Details]
WHERE Orders.OrderID = [Order Details].OrderID
ORDER BY Orders.OrderID
FOR XML AUTO, XMLDATA
以上的SQL语句产生以下结果:
ELEMENTS
ELEMENTS选项指示各数据列作为子元素而非属性返回。假如你采用AUTO模式就可以只采用该选项。
BINARY BASE64
使用该选项表示你希望采用base64编码格式表示二进制数据。
采用XML子句的说法可就多了,你最好参考下SQL在线图书。
在线指南
本文只是对FOR XML子句的简单说明,这里要提醒你的是这一部分不过是XML同SQL Server集成需要注意的一点,其他方面的问题还包括IIS的OPENXML 函数和模版文件等。看来真是这样,SQL Server的每个毛孔都滴着XML这种东西。
原文转自:www.ltesting.net
篇4:恢复被使用数据库
恢复被使用数据库
?
use master
go
exec Sp_KillAllProcessInDB 'guagua_goods_config'
go
---以下为恢复备份时, 通过脚本生成的内容
RESTORE DATABASE [guagua_goods_config] FROM DISK = N'C:\guaguagoods备份\guagua_goods_config_backup__10_06_030006_6311039.bak' WITH FILE = 1, MOVE N'guagua_goods_config' TO N'D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\guagua_goods_config.mdf', MOVE N'guagua_goods_config_log' TO N'D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\guagua_goods_config.ldf', NOUNLOAD, REPLACE, STATS = 10
GO
篇5:Oracle数据库游标使用
SQL是用于访问ORACLE数据库的语言,PL/SQL扩展和加强了SQL的功能,它同时引入了更强的程序逻辑, PL/SQL支持DML命令和SQL的事务控制语句。DDL在PL/SQL中不被支持,这就意味作在PL/SQL程序块中不能创建表或其他任何对象。较好的PL/SQL程序设计是在PL/SQL块中使用象DBMS_SQL这样的内建包或执行EXECUTE IMMEDIATE命令建立动态SQL来执行DDL命令,PL/SQL编译器保证对象引用以及用户的权限。
下面我们将讨论各种用于访问ORACLE数据库的DDL和TCL语句。
查询
SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中。SELECT INTO语法如下:
SELECT [DISTICT|ALL]{*|column[,column,...]}INTO (variable[,variable,...] |record)FROM {table|(sub-query)}[alias]WHERE............PL/SQL中SELECT语句只返回一行数据。如果超过一行数据,那么就要使用显式游标(对游标的讨论我们将在后面进行),INTO子句中要有与SELECT子句中相同列数量的变量。INTO子句中也可以是记录变量。
%TYPE属性
在PL/SQL中可以将变量和常量声明为内建或用户定义的数据类型,以引用一个列名,同时继承他的数据类型和大小。这种动态赋值方法是非常有用的,比如变量引用的列的数据类型和大小改变了,如果使用了%TYPE,那么用户就不必修改代码,否则就必须修改代码。
例:
v_empno SCOTT.EMP.EMPNO%TYPE;v_salary EMP.SALARY%TYPE;不但列名可以使用%TYPE,而且变量、游标、记录,或声明的常量都可以使用%TYPE。这对于定义相同数据类型的变量非常有用。
DELCAREV_A NUMBER(5):=10;V_B V_A%TYPE:=15;V_C V_A%TYPE;BEGINDBMS_OUTPUT.PUT_LINE('V_A='||V_A||'V_B='||V_B||'V_C='||V_C);ENDSQL>/V_A=10 V_B=15 V_C=PL/SQL procedure successfully completed.SQL>其他DML语句
其它操作数据的DML语句是:INSERT、UPDATE、DELETE和LOCK TABLE,这些语句在PL/SQL中的语法与在SQL中的语法相同。我们在前面已经讨论过DML语句的使用这里就不再重复了。在DML语句中可以使用任何在DECLARE部分声明的变量,如果是嵌套块,那么要注意变量的作用范围。
例:
CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number)ASv_ename EMP.ENAME%TYPE;BEGINSELECT ename INTO v_enameFROM empWHERE empno=p_empno;INSERT INTO FORMER_EMP(EMPNO,ENAME)VALUES (p_empno,v_ename);DELETE FROM empWHERE empno=p_empno;UPDATE former_empSET date_deleted=SYSDATEWHERE empno=p_empno;EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('Employee Number Not Found!');ENDDML语句的结果
当执行一条DML语句后,DML语句的结果保存在四个游标属性中,这些属性用于控制程序流程或者了解程序的状态。当运行DML语句时,PL/SQL打开一个内建游标并处理结果,游标是维护查询结果的内存中的一个区域,游标在运行DML语句时打开,完成后关闭。隐式游标只使用SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT三个属性.SQL%FOUND,SQL%NOTFOUND是布尔值,SQL%ROWCOUNT是整数值。
SQL%FOUND和SQL%NOTFOUND
在执行任何DML语句前SQL%FOUND和SQL%NOTFOUND的值都是NULL,在执行DML语句后,SQL%FOUND的属性值将是:
. TRUE :INSERT
. TRUE :DELETE和UPDATE,至少有一行被DELETE或UPDATE.
. TRUE :SELECT INTO至少返回一行
当SQL%FOUND为TRUE时,SQL%NOTFOUND为FALSE。
SQL%ROWCOUNT
在执行任何DML语句之前,SQL%ROWCOUNT的值都是NULL,对于SELECT INTO语句,如果执行成功,SQL%ROWCOUNT的值为1,如果没有成功,SQL%ROWCOUNT的值为0,同时产生一个异常NO_DATA_FOUND.
SQL%ISOPEN
SQL%ISOPEN是一个布尔值,如果游标打开,则为TRUE, 如果游标关闭,则为FALSE.对于隐式游标而言SQL%ISOPEN总是FALSE,这是因为隐式游标在DML语句执行时打开,结束时就立即关闭。
事务控制语句
事务是一个工作的逻辑单元可以包括一个或多个DML语句,事物控制帮助用户保证数据的一致性。如果事务控制逻辑单元中的任何一个DML语句失败,那么整个事务都将回滚,在PL/SQL中用户可以明确地使用COMMIT、ROLLBACK、SAVEPOINT以及SET TRANSACTION语句。
COMMIT语句终止事务,永久保存数据库的变化,同时释放所有LOCK,ROLLBACK终止现行事务释放所有LOCK,但不保存数据库的任何变化,SAVEPOINT用于设置中间点,当事务调用过多的数据库操作时,中间点是非常有用的,SET TRANSACTION用于设置事务属性,比如read-write和隔离级等。
显式游标
当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用select into语句。PL/SQL管理隐式游标,当查询开始时隐式游标打开,查询结束时隐式游标自动关闭。显式游标在PL/SQL块的声明部分声明,在执行部分或异常处理部分打开,取数据,关闭。下表显示了显式游标和隐式游标的差别:
表1 隐式游标和显式游标
隐式游标显式游标 PL/SQL维护,当执行查询时自动打开和关闭在程序中显式定义、打开、关闭,游标有一个名字。 游标属性前缀是SQL游标属性的前缀是游标名 属性%ISOPEN总是为FALSE%ISOPEN根据游标的状态确定值 SELECT语句带有INTO子串,只有一行数据被处理可以处理多行数据,在程序中设置循环,取出每一行数据。使用游标
这里要做一个声明,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标。要在程序中使用游标,必须首先声明游标。
声明游标
语法:
CURSOR cursor_name IS select_statement;在PL/SQL中游标名是一个未声明变量,不能给游标名赋值或用于表达式中。
例:
DELCARECURSOR C_EMP IS SELECT empno,ename,salaryFROM empWHERE salary>ORDER BY ename;........BEGIN在游标定义中SELECT语句中不一定非要表可以是视图,也可以从多个表或视图中选择的列,甚至可以使用*来选择所有的列 。
打开游标
使用游标中的值之前应该首先打开游标,打开游标初始化查询处理。打开游标的语法是:
OPEN cursor_namecursor_name是在声明部分定义的游标名。
例:
OPEN C_EMP;关闭游标
语法:
CLOSE cursor_name例:
CLOSE C_EMP;从游标提取数据
从游标得到一行数据使用FETCH命令。每一次提取数据后,游标都指向结果集的下一行。语法如下:
FETCH cursor_name INTO variable[,variable,...]对于SELECT定义的游标的每一列,FETCH变量列表都应该有一个变量与之相对应,变量的类型也要相同。
例:
SET SERVERIUTPUT ONDECLAREv_ename EMP.ENAME%TYPE;v_salary EMP.SALARY%TYPE;CURSOR c_emp IS SELECT ename,salary FROM emp;BEGINOPEN c_emp;FETCH c_emp INTO v_ename,v_salary;DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename||'is'|| v_salary);FETCH c_emp INTO v_ename,v_salary;DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename||'is'|| v_salary);FETCH c_emp INTO v_ename,v_salary;DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename||'is'|| v_salary);CLOSE c_emp;END这段代码无疑是非常麻烦的,如果有多行返回结果,可以使用循环并用游标属性为结束循环的条件,以这种方式提取数据,程序的可读性和简洁性都大为提高,下面我们使用循环重新写上面的程序:
SET SERVERIUTPUT ONDECLAREv_ename EMP.ENAME%TYPE;v_salary EMP.SALARY%TYPE;CURSOR c_emp IS SELECT ename,salary FROM emp;BEGINOPEN c_emp;LOOPFETCH c_emp INTO v_ename,v_salary;EXIT WHEN c_emp%NOTFOUND;DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename||'is'|| v_salary);END记录变量
定义一个记录变量使用TYPE命令和%ROWTYPE,关于%ROWsTYPE的更多信息请参阅相关资料,
记录变量用于从游标中提取数据行,当游标选择很多列的时候,那么使用记录比为每列声明一个变量要方便得多。---www.bianceng.cn
当在表上使用%ROWTYPE并将从游标中取出的值放入记录中时,如果要选择表中所有列,那么在SELECT子句中使用*比将所有列名列出来要安全得多。
例:
SET SERVERIUTPUT ONDECLARER_emp EMP%ROWTYPE;CURSOR c_emp IS SELECT * FROM emp;BEGINOPEN c_emp;LOOPFETCH c_emp INTO r_emp;EXIT WHEN c_emp%NOTFOUND;DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);END LOOP;CLOSE c_emp;END;%ROWTYPE也可以用游标名来定义,这样的话就必须要首先声明游标:
SET SERVERIUTPUT ONDECLARECURSOR c_emp IS SELECT ename,salary FROM emp;R_emp c_emp%ROWTYPE;BEGINOPEN c_emp;LOOPFETCH c_emp INTO r_emp;EXIT WHEN c_emp%NOTFOUND;DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);END LOOP;CLOSE c_emp;END;带参数的游标
与存储过程和函数相似,可以将参数传递给游标并在查询中使用。这对于处理在某种条件下打开游标的情况非常有用。它的语法如下:
CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;定义参数的语法如下:
Parameter_name [IN] data_type[{:=|DEFAULT} value]与存储过程不同的是,游标只能接受传递的值,而不能返回值。参数只定义数据类型,没有大小。
另外可以给参数设定一个缺省值,当没有参数值传递给游标时,就使用缺省值。游标中定义的参数只是一个占位符,在别处引用该参数不一定可靠。
在打开游标时给参数赋值,语法如下:
OPEN cursor_name[value[,value]....];参数值可以是文字或变量。
例:
DECALRECURSOR c_dept IS SELECT * FROM dept ORDER BY deptno;CURSOR c_emp (p_dept VARACHAR2) ISSELECT ename,salaryFROM empWHERE deptno=p_deptORDER BY enamer_dept DEPT%ROWTYPE;v_ename EMP.ENAME%TYPE;v_salary EMP.SALARY%TYPE;v_tot_salary EMP.SALARY%TYPE;BEGINOPEN c_dept;LOOPFETCH c_dept INTO r_dept;EXIT WHEN c_dept%NOTFOUND;DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);v_tot_salary:=0;OPEN c_emp(r_dept.deptno);LOOPFETCH c_emp INTO v_ename,v_salary;EXIT WHEN c_emp%NOTFOUND;DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);v_tot_salary:=v_tot_salary+v_salary;END LOOP;CLOSE c_emp;DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);END LOOP;CLOSE c_dept;END;游标FOR循环
在大多数时候我们在设计程序的时候都遵循下面的步骤:
1、打开游标
2、开始循环
3、从游标中取值
4、检查那一行被返回
5、处理
6、关闭循环
7、关闭游标
可以简单的把这一类代码称为游标用于循环。但还有一种循环与这种类型不相同,这就是FOR循环,用于FOR循环的游标按照正常的声明方式声明,它的优点在于不需要显式的打开、关闭、取数据,测试数据的存在、定义存放数据的变量等等。游标FOR 循环的语法如下:
FOR record_name IN(corsor_name[(parameter[,parameter]...)]| (query_difinition)LOOPstatementsEND LOOP;下面我们用for循环重写上面的例子:
DECALRECURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno;CURSOR c_emp (p_dept VARACHAR2) ISSELECT ename,salaryFROM empWHERE deptno=p_deptORDER BY enamev_tot_salary EMP.SALARY%TYPE;BEGINFOR r_dept IN c_dept LOOPDBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);v_tot_salary:=0;FOR r_emp IN c_emp(r_dept.deptno) LOOPDBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);v_tot_salary:=v_tot_salary+v_salary;END LOOP;DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);END LOOP;END;在游标FOR循环中使用查询
在游标FOR循环中可以定义查询,由于没有显式声明所以游标没有名字,记录名通过游标查询来定义。
DECALREv_tot_salary EMP.SALARY%TYPE;BEGINFOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOPDBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);v_tot_salary:=0;FOR r_emp IN (SELECT ename,salaryFROM empWHERE deptno=p_deptORDER BY ename) LOOPDBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);v_tot_salary:=v_tot_salary+v_salary;END LOOP;DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);END LOOP;END;游标中的子查询
语法如下:
CURSOR C1 IS SELECT * FROM empWHERE deptno NOT IN (SELECT deptnoFROM deptWHERE dname!='ACCOUNTING');可以看出与SQL中的子查询没有什么区别。
游标中的更新和删除
在PL/SQL中依然可以使用UPDATE和DELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下使用。PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法。
UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR UPDATE子串,当对话使用FOR UPDATE子串打开一个游标时,所有返回集中的数据行都将处于行级(ROW-LEVEL)独占式锁定,其他对象只能查询这些数据行,不能进行UPDATE、DELETE或SELECT...FOR UPDATE操作。
语法:
FOR UPDATE [OF [schema.]table.column[,[schema.]table.column]..[nowait]在多表查询中,使用OF子句来锁定特定的表,如果忽略了OF子句,那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会话锁定,那么正常情况下ORACLE将等待,直到数据行解锁。
在UPDATE和DELETE中使用WHERE CURRENT OF子串的语法如下:
WHERE{CURRENT OF cursor_name|search_condition}例:
DELCARECURSOR c1 IS SELECT empno,salaryFROM empWHERE comm IS NULLFOR UPDATE OF comm;v_comm NUMBER(10,2);BEGINFOR r1 IN c1 LOOPIF r1.salary<500 THENv_comm:=r1.salary*0.25;ELSEIF r1.salary<1000 THENv_comm:=r1.salary*0.20;ELSEIF r1.salary<3000 THENv_comm:=r1.salary*0.15;ELSEv_comm:=r1.salary*0.12;END IF;UPDATE emp;SET comm=v_commWHERE CURRENT OF c1l;END LOOP;END篇6:车辆管理信息系统异构数据库集成方法研究
车辆管理信息系统异构数据库集成方法研究
在军交运输车辆管理系统信息化建设中,由于缺乏权威的顶层设计而存在大量的`异构数据库,如何集成异构数据库、解决信息孤岛现象,提出了利用数据仓库技术和中间件技术这两种比较理想的方法来集成异构数据库,并给出了车辆管理信息系统异构数据库集成的解决方案.
作 者:迟亚利 鲍利平CHI Ya-li BAO Li-ping 作者单位:汽车管理学院,车辆管理系,安徽,蚌埠,233011 刊 名:军事交通学院学报 英文刊名:JOURNAL OF ACADEMY OF MILITARY TRANSPORTATION 年,卷(期): 11(2) 分类号:U491 关键词:异构数据库 数据仓库 数据集成 中间件篇7:如何学会使用db2指令数据库
MI LY: Arial; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt”>1 、看 图解 在使用 DB2 帮助及在查阅各种文档时,会碰到命令解释图解,所以,学会使用 DB2 指令,首选需要了解在 DB2 帮助中常用的两种命令图解, 命令的 语法 以图的形式存在。图告知您
MILY: Arial; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">1、看图解
在使用DB2帮助及在查阅各种文档时,会碰到命令解释图解,所以,学会使用DB2指令,首选需要了解在DB2帮助中常用的两种命令图解。
命令的语法以图的形式存在。图告知您可使用特殊命令执行的操作,并且表明不同选项之前以及有时同一选项的不同值之间的关系。DB2中常用的语法图解有两种不同类型:轨道图和BNF(Backus-Naur格式)图。
==>如何读轨道图
每个轨道图由两个右箭头开始并且以一对左右箭头结束。由单个右箭头开始的行是延续行。您从左到右,从上到下,按照箭头的方向读轨道图。
用于轨道图的其它约定是:
>>-A--B--C-----------------------------------------------------><
您必须指定值A、B和C。必需值在轨道图的主行上显示。
>>-+---+-------------------------------------------------------><
'-A-'
您可指定值A。在轨道图的主行下显示可选值。
>>-+-A-+-------------------------------------------------------><
+-B-+
'-C-'
值A、B和C是可选的,您必须指定其中一个。
>>-+---+-------------------------------------------------------><
+-A-+
+-B-+
'-C-'
值A、B和C是可选的,您可指定其中一个,
.-,-----.
V |
>>---+---+-+---------------------------------------------------><
+-A-+
+-B-+
'-C-'
您可指定A、B和C的一个或多个值。多个或重复的值的任何必需分隔符(在这个示例中是逗号(,))显示在箭头上。
.-+---+-.
| '-,-' |
V |
>>---+---+-+---------------------------------------------------><
'-A-'
您可多次指定值A。此示例中的分隔符是可选的。
.-A-.
>>-+---+-------------------------------------------------------><
+-B-+
'-C-'
值A、B和C是可选的,您可指定其中一个。如果未指定显示的值,则使用缺省值A(主行上显示的值)。
>>-|名称|----------------------------------------------------><
名称
|--A--+---+-----------------------------------------------------|
'-B-'
从主轨道图中分别显示轨道片段名称。
标点符号和大写值按所示准确无误地指定。
小写值(例如,name)提供您自己的文本代替name变量。
共5页: 1 [2] [3] [4] [5] 下一页
原文转自:www.ltesting.net
篇8:使用oralce Cursor数据库教程
使用Cursor:
declare
RoomID Room.RoomID%Type;
RoomName Room.RoomName%Type;
cursor crRoom is
select RoomID,RoomName
from Room;
begin
open crRoom;
loop;
fetch crRoom into RoomID,RoomName;
exit when crRoom%notFound;
end loop;
close crRoom;
end;
3.1在游标使用入口参数
在SQL语句的Where 子句中恰当使用 相关语句简化逻辑,本来需要使用两个游标,把相关入口参数放入到SQL语句的Where 子句中,一个就搞定了:
cursor crRoom is
select
distinct 楼层,房屋用途
from TT_没有处理的房屋 t
where 数据级别>= 0
and 房屋处理类别= 3
and 产权编号=p_产权编号
and 拆迁房屋类别=p_拆迁房屋类别
and 面积>0
and (not p_房屋用途 is null
and 房屋用途=p_房屋用途
or p_房屋用途 is null);
另外一个例子:
CREATE OR REPLACE PROCEDURE PrintStudents(
p_Major IN students.major%TYPE) AS
CURSOR c_Students IS
SELECT first_name, last_name
FROM students
WHERE major = p_Major;
BEGIN
FOR v_StudentRec IN c_Students LOOP
DBMS_OUTPUT.PUT_LINE(v_StudentRec.first_name || ' ' ||
v_StudentRec.last_name);
END LOOP;
END;
Oracle带的例子examp6.sql
DECLARE
CURSOR bin_cur(part_number NUMBER) IS SELECT amt_in_bin
FROM bins
WHERE part_num = part_number AND
amt_in_bin >0
ORDER BY bin_num
FOR UPDATE OF amt_in_bin;
bin_amt bins.amt_in_bin%TYPE;
total_so_far NUMBER(5) := 0;
amount_needed CONSTANT NUMBER(5) := 1000;
bins_looked_at NUMBER(3) := 0;
BEGIN
OPEN bin_cur(5469);
WHILE total_so_far < amount_needed LOOP
FETCH bin_cur INTO bin_amt;
EXIT WHEN bin_cur%NOTFOUND;
/* If we exit, there's not enough to *
* satisfy the order. */
bins_looked_at := bins_looked_at + 1;
IF total_so_far + bin_amt < amount_needed THEN
UPDATE bins SET amt_in_bin = 0
WHERE CURRENT OF bin_cur;
-- take everything in the bin
total_so_far := total_so_far + bin_amt;
ELSE -- we finally have enough
UPDATE bins SET amt_in_bin = amt_in_bin
- (amount_needed - total_so_far)
WHERE CURRENT OF bin_cur;
total_so_far := amount_needed;
END IF;
END LOOP;
CLOSE bin_cur;
INSERT INTO temp VALUES (NULL, bins_looked_at, '<- bins looked at');
COMMIT;
END;
-- Created on 2004-8-9 by ADMINISTRATOR
declare
--带有变量的Cursor
cursor crBooks(c_bookTitle varchar2) is
select *
from books a
where a.title like c_bookTitle||'%';
begin
for v_Books in crBooks('Oracle8') loop
dbms_output.put_line(v_Books.author1);
end loop;
end;











