1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional XML Databases phần 10 pptx

84 231 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

SQL Server 2000 XML Sample Applications 779 The second template is a little more complicated, as it uses the updategram to allow the user to edit the record. We explored using updategrams in Chapter 15. This template is called ch20_ex17.xml. <ROOT xmlns:updg="urn:schemas-microsoft-com:xml-updategram"> <updg:header> <updg:param name="eid"/> <updg:param name="fname" /> <updg:param name="lname" /> </updg:header> <updg:sync > <updg:before> <EditEmployees eid="$eid" /> </updg:before> <updg:after> <EditEmployees eid="$eid" fname="$fname" lname="$lname" /> </updg:after> </updg:sync> </ROOT> The template will take the employee id, and use this to select the appropriate record, because we do not allow the user to re-write the id for the user (only the names) we write this back in to make sure that it overwrites the correct record. Save this in the same place as the first template. Writing the ASP Page Now we come on to the main ASP page. Since the page we will be creating is an ASP application, it must be placed in a virtual root, which must be created using the Internet Services Manager tool. You cannot use the virtual root that was created using the IIS Virtual Directory Management for SQL Server utility, because that virtual root is only configured for use with SQL Server and cannot handle ASP requests. To create a new virtual root for the ASP application, start the Internet Services Manager tool. To create a new virtual directory, highlight the Default Web Site, go to the Action menu, and select New. Provide the virtual directory name, and then path to the physical directory in which the following ASP application will be saved (ch20_ex17.asp). Let's step through the code for the ASP Page and see what it is doing here. We start by declaring our scripting language, VBScript, and the EmpID variable to hold the EmpID. : <% LANGUAGE=VBSCRIPT %> <% Dim EmpID Remember that, if the user is loading the page for the first time, we want to show them the form to collect user data, so we need to check if the id has been specified. So, we set EmpID to the value of the input box that would contain the employee id if the user had already seen the form. We then write out the start of the HTML code for the page to be displayed, and start an if then statement to display the first form if the id has not been specified. EmpID=Request.Form("eid") %> <html> <body> <% 'if employee id value is not yet provided, display this form if EmpID="" then %> Chapter 20 780 If EmpID is empty, we start the <FORM> element and write that back to the client. When the user submits the id, it will be posted back to the same ASP page. <! the EmpID has not been specified so we display the form that allows users to enter an id > <form action="ch20_ex16.asp" method="POST"> <br> Enter EmpID: <input type=text name="eid"><br> <input type=submit value="Submit this ID" ><br><br> Once the user has specified an id, we get passed onto this section, which creates retrieves the record. < Otherwise, we have already entered an employee ID, so display the second part of the form where the user can change fname and lname > <% else %> <form name="Employee" action="http://localhost/VirtualRoot/Template/Ch20_ex17.xml" method="POST"> You may update the first name and last name information below.<br><br> <! comment goes here to separate the parts of the application or page > <br> <% ' Let us load the document in the parser and extract the values to populate the form. Set objXML=Server.CreateObject("MSXML2.DomDocument") objXML.async=False objXML.Load("http://localhost/northwind/Template/Ch20_ex16.xml?eid=" & EmpID) set objEmployee=objXML.documentElement.childNodes.Item(0) ' In retrieving data form the database, if a value in the column is NULL, ' we don't get any attribute for the corresponding element. In this ' case we want to skip the error generation and go to the next attribute On Error Resume Next ' get the eid attribute value Response.Write "Emp ID: <input type=text readonly=true style='background- color:silver' name=eid value=""" Response.Write objEmployee.attributes(0).value Response.Write """><br><br>" ' get the fname attribute value Response.Write "First Name: <input type=text name=fname value=""" Response.Write objEmployee.attributes(1).value Response.Write """><br><br>" SQL Server 2000 XML Sample Applications 781 ' the "lname" attribute Response.Write "Last Name: <input type=text name=lname value=""" Response.Write objEmployee.attributes(2).value Response.Write """><br>" set objEmployee=Nothing Set objXML=Nothing %> <input type="submit" value="Submit this change" ><br><br> <input type=hidden name="contenttype" value="text/xml"> <input type=hidden name="eeid" value="<%=EmpID%>"><br><br> <% end if %> </form> </body> </html> This example illustrates how easy it is to write ASP applications to retrieve and process XML with SQL Server XML functionality. The size of the code is much smaller and the application is more secure as all the business logic is controlled by the server and not present in the HTML transmitted to the client. Sample ADO Applications Having seen how to pass the records as XML across HTTP using URLs to call templates, we will now look at how we can use ADO from a Visual Basic form. ADO is a client dependent method of accessing and manipulating SQL Server data using XML. The clients must have Microsoft Data Access Components 2.6 or higher for this functionality. One immediate advantage of this method is a distributed load. Whereas in ASP applications the server handles all the processing of data, client-side ADO applications use the processing power of the client to manage data. One of the more likely usages of ADO is the custom client applications that may require high speed batch editing of data sets where an HTML interface may not be appropriate. For a more complete discussion of the XML capabilities of ADO and ADO+, refer to chapter 13. In this Visual Basic application a command is executed using ADO. The command executes a simple SELECT query against the Northwind database. The query specifies the FOR XML clause. Therefore, instead of getting a record set, XML is returned upon the execution of the command, and since the result itself is XML, it must be returned as a stream. It is important to note here that the structure of the returned XML document is entirely controlled by the query executed. This method is more flexible than using other ADO features which transform record sets into XML documents. Executing a Command To get us going with using VB and ADO, we'll start by simply executing a SELECT statement that is hard coded into the VB form. The SELECT statement uses the FOR XML clause to return XML as a string that is displayed to the user. Start up Visual Basic and create a new Visual Basic Project. A Standard EXE project is sufficient. Add a reference to ADO 2.6. We need at least this version because earlier versions of ADO where not designed to work with SQL Server XML features. This code can be found in the download, saved as ch20_ex18: Chapter 20 782 Private Sub Form_Load() Dim cmd As New ADODB.Command Dim conn As New ADODB.Connection Dim strmOut As New ADODB.Stream ' Open a connection to the SQL Server. conn.Provider = "SQLOLEDB" conn.Open "server=(local); database=Northwind; uid=sa; " Set cmd.ActiveConnection = conn cmd.CommandText = "SELECT FirstName, LastName FROM Employees FOR XML AUTO" ' Execute the command, open the return stream, and read the result. strmOut.Open strmOut.LineSeparator = adCRLF cmd.Properties("Output Stream").Value = strmOut cmd.Execute , , adExecuteStream strmOut.Position = 0 Debug.Print strmOut.ReadText End Sub When we run this application it will retrieve the records from Northwind specified in the query, and displays them in the immediate window: Executing an XML Template Now let's look at an example that makes use of an XML template. This time, we will be using ADO to execute the template. There are three key parts to this example: ❑ We use the FileSystemObject to open a text stream over a text file, which contains the XML template. This method returns TextStream object. ❑ The data in this stream is passed to an ADO stream. To do this we convert the TextStream object into ADOStream object which is understood by the ADO command object (cmd). We need to do this because the ADO command object doesn't understand TextStream, but does understand ADOStream. ❑ The ADO stream is then executed using the connection to SQL Server. In testing this application, you must include the Microsoft Scripting Runtime project reference. It contains the FileSystemObject, which is needed to perform the file operations. You also need a reference to ADO 2.6. Let's step through this code (ch20_ex20): The application first opens a standard connection to SQL Server 2000 using the ADO connection object (ADODB.Connection). SQL Server 2000 XML Sample Applications 783 Private Sub Form_Load() Dim cmd As New ADODB.Command Dim conn As New ADODB.Connection Dim strmIn As New ADODB.Stream Dim txtStream As TextStream Dim strmOut As New ADODB.Stream Dim objFSO As New FileSystemObject ' Open a connection to the SQL Server. conn.Provider = "SQLOLEDB" conn.Open "server=(local); database=Northwind; uid=sa; " Set cmd.ActiveConnection = conn Next we set the dialect for the ADO command object (ADODB.Command). Since you are executing an XML template, we must set the ADO commands dialect to MSSQLXML. This setting instructs ADO to specifically interact with SQL Server XML features. ' Set the command dialect to XML (DBGUID_MSSQLXML). cmd.Dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}" Then a stream is opened over the XML template file using the OpenTextFile method of the FileSystemObject (objFSO). Using the ReadALL method on the TextStream object (txtStream), the contents of the template file are written into an ADO stream (strmIn). The position of each stream is reset to 0 prior to executing the command and prior to reading the result. We use the TextStream.ReadALL command to return a string and then later used this string to create the ADOStream object. ' Open the command stream and write our template to it. strmIn.Open Set txtStream = objFSO.OpenTextFile("C:\inetpub\wwwroot\Northwind\template\ch20_ex20.xml",_ ForReading) strmIn.WriteText txtStream.ReadAll strmIn.Position = 0 The ADO stream (strmIn) is then assigned to the CommandStream property of the ADO command object (cmd). Set cmd.CommandStream = strmIn To execute the template we first open the output stream (strmOut.Open) and set the command's Output Stream property to this stream. ' Execute the command, open the return stream, and read the result. strmOut.Open strmOut.LineSeparator = adCRLF cmd.Properties("Output Stream").Value = strmOut Finally the command's execute method (cmd.Execute) is called specifying adExecuteStream as the third parameter (the options parameter). The data in the output stream (strmOut) is accessed using the ReadText method of the ADO stream object (ADODB.Stream). Chapter 20 784 cmd.Execute , , adExecuteStream strmOut.Position = 0 Debug.Print strmOut.ReadText End Sub Here is the sample XML template that is executed in our Visual Basic application. Save this template (ch20_ex20.xml) in the directory associated with virtual name of template type (it doesn't have to be in this directory for ADO application. But we will use the same template in another application later): <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" > <sql:query> SELECT FirstName, LastName FROM Employees where EmployeeID=1 FOR XML AUTO </sql:query> </ROOT> As before the results are passed to the immediate window. Passing Parameters The next application is similar to the previous one, except for the following: ❑ The XML template executes an XPath query against XML View ❑ This template accepts one parameter which must be passed through ADO The Visual Basic application is given below. It is similar to the previous example except now parameter information is added in the code. Here is the code again; we have highlighted the differences in the two versions: Private Sub Form_Load () Dim cmd As New ADODB.Command Dim conn As New ADODB.Connection Dim strmIn As New ADODB.Stream Dim txtStream As TextStream Dim strmOut As New ADODB.Stream Dim objFSO As New FileSystemObject Prior to executing the command, an ADO parameter (ADODB.Parameter) is added to the command object's parameters collection. This parameter stores The employeeID, which is required by the XPath query in the template. Dim objParam As ADODB.Parameter ' Open a connection to the SQL Server. conn.Provider = "SQLOLEDB" conn.Open "server=(local); database=Northwind; uid=sa; " Set cmd.ActiveConnection = conn SQL Server 2000 XML Sample Applications 785 ' Set the command dialect to XML (DBGUID_MSSQLXML). cmd.Dialect = "{5d531cb2-e6ed-11d2-b252-00c04f681b71}" ' Open the command stream and write our template to it. strmIn.Open Set txtStream = objFSO.OpenTextFile("C:\inetpub\wwwroot\Northwind\template\ch20_ex21.xml",_ ForReading) strmIn.WriteText txtStream.ReadAll strmIn.Position = 0 Set cmd.CommandStream = strmIn ' Execute the command, open the return stream, and read the result. strmOut.Open strmOut.LineSeparator = adCRLF cmd.Properties("Output Stream").Value = strmOut The parameter name must be prefixed with the @ in the parameter's definition. The parameter is marked as an input parameter by specifying adParamInput as the value of the Direction property. The value of the Size property determines the maximum number of characters that will be passed to the template. In this example 25 is sufficient. In passing parameters to templates that execute an XPath query, note that XPath can use only string-valued parameters. Set objParam = cmd.CreateParameter objParam.Name = "@EmployeeID" objParam.Direction = adParamInput objParam.Type = adWChar objParam.Size = 25 objParam.Value = "6" cmd.Parameters.Append objParam cmd.NamedParameters = True cmd.Execute , , adExecuteStream strmOut.Position = 0 Debug.Print strmOut.ReadText End Sub In testing this application (ch20_ex21), you must include the Microsoft Scripting Runtime project reference. It contains the FileSystemObject, which is needed to perform the file operations, as well as a reference to the ADO 2.6 library. Now let's look at the revised template. Notice that the XML template specifies XML view using an inline XDR schema. Since the schema is inline, the value of mapping-schema attribute has the '#' character in the beginning indicating the schema is inline (in the same template file). In the XPath query: Employees[@EmployeeID=$EmployeeID] Chapter 20 786 the $EmployeeID is the parameter passed to the template. The query retrieves Employees elements with specific value for its EmployeeID attribute. The template parameter is defined in the <sql:header> tag in the template. Save this template (ch20_ex21.xml) in the directory associated with the virtual name of template type (it can be anywhere for this application but we will use this template in later examples, executed in the URL). <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <Schema xmlns="urn:schemas-microsoft-com:xml-data" sql:id="MyMappingSchema" sql:is-mapping-schema="1"> <ElementType name="Employees" > <AttributeType name="EmployeeID" /> <AttributeType name="FirstName" /> <AttributeType name="LastName" /> <attribute type="EmployeeID" /> <attribute type="FirstName" /> <attribute type="LastName" /> </ElementType> </Schema> <sql:header> <sql:param name='EmployeeID'>1</sql:param> </sql:header> <sql:xpath-query mapping-schema="#MyMappingSchema"> Employees[@EmployeeID=$EmployeeID] </sql:xpath-query> </ROOT> Again the results are printed out to the immediate window. Having seen some examples of accessing SQL server's XML capabilities over HTTP, let's look at a more integrated case study that brings together some of the ideas that we have seen so far. Building an Empire: an eLemonade Company For the rest of this chapter, we will use a prototype e-commerce scenario to demonstrate the use of OpenXML, FOR XML, XPath, and Updategrams. All of these technologies may be used independently or together with others; however, a natural pairing is OpenXML with FOR XML, and XPath with Updategrams. We will present a scenario and two solutions, one for each pair of technologies. The solutions presented demonstrate the strengths and weaknesses of these technologies. We begin by describing the requirements for this project, and then outlining solutions to some of the problems presented. Next, we explore a solution using OPENXML and FOR XML, and then consider a different solution using XML Views, XPath, and Updategrams. The Internet Lemonade Stand – Project Requirements Let's suppose that you've decided to open your storefront online, and you've identified your target market: thirsty web surfers. Recalling a classic computer game, you are suddenly inspired: Yes, that's right, this will be the Internet lemonade stand. SQL Server 2000 XML Sample Applications 787 Based on years of experience and substantial research in the lemonade stand business, you quickly determine the requirements for your project. Of course, you're selling online, so weather is no longer an issue - it's always sunny somewhere! There are, however, other issues to consider: ❑ You need lemons, and lots of them. You need a way to track your supplies of lemons and sugar. ❑ Of course, you need to track sales and shipping information. ❑ You need to keep a sharp eye on market trends, so you will need to track various news feeds for bulletins that could impact your online lemonade retail business. ❑ Customer loyalty is the key to your success, so you decide to allow users to create profiles to customize the web site layout (and maybe someday track buying patterns over time, to provide targeted advertising). You're going to develop this web site entirely on your own using the super-cool XML features of SQL Server 2000, so your development budget will be smaller than usual. In fact, it will be negligible in this example, because we're going to do all the work for you. All you need to do is follow the preparatory steps below, using the sample code provided with this book. The sample code assumes that you have created a SQL virtual directory named lemonade with a virtual name template to execute template queries. Replace all instances of http://localhost/ lemonade/template in this example with your actual server location and virtual directory names. Database Design In this example, we've chosen a design that allows us to highlight various features of XML support in SQL Server 2000, but one that also shares many characteristics with real-world scenarios. We will not go into all the details of setting up the database, but will instead highlight some relevant points, such as the table structure. Let's suppose that with the exception of news feeds that allow you to track market trends, you supply all the data yourself (supply costs, advertising costs, sales and revenues). After examining your requirements in detail, you decide to store the data in the database in five tables: Chapter 20 788 This database, and the tables within it can be created using the following script (ch20_ex22.sql): CREATE DATABASE LEMONADE GO USE LEMONADE GO The NEWS table stores all the news bulletins you collect CREATE TABLE NEWS (Date datetime not null, publication date Headline nvarchar(100) not null, news headline Story ntext not null) news content The PURCHASES table stores all the expenditures you make CREATE TABLE PURCHASES (Pid int identity primary key, purchase id Date datetime not null, date purchased Price money not null, total cost in dollars Notes nvarchar(100)) description or other comments The SUPPLIES table tracks lemon and sugar supplies CREATE TABLE SUPPLIES (Pid int foreign key references Purchases (Pid), corresponding purchase Item nvarchar(10) not null, lemon, sugar Quantity smallint not null) number of lemons, kilograms sugar The CUSTOMERS table keeps customer-specific information CREATE TABLE CUSTOMERS (Cid nvarchar(12) primary key, customer id Name nvarchar(50), customer name Color nvarchar(20)) favorite color The ORDERS table stores all orders placed through the Internet Lemonade Stand CREATE TABLE ORDERS (Oid int identity primary key, order id OrderDate datetime not null, time order was placed ShipDate datetime, time order was fulfilled Cid nvarchar(12) foreign key references Customers (cid), customer who placed order Quantity smallint not null, liters of lemonade UnitPrice money not null) dollars per liter I'd suggest creating these tables in a new database to keep your examples separate and thus more logically distributed. (I've called mine lemonade), Let's also prepare the database with a customer and initial inventory (Mom kindly supplied sugar for free), by running the following (ch20_ex23.sql) against our lemonade database: INSERT INTO PURCHASES VALUES ('1999-10-19', 0.00, 'thanks, Mom!') INSERT INTO SUPPLIES VALUES (@@identity, 'sugar', 2) INSERT INTO PURCHASES VALUES ('1999-10-19', 5.00, NULL) INSERT INTO SUPPLIES VALUES (@@identity, 'lemon', 20) INSERT INTO CUSTOMERS VALUES ('ad', 'Arthur Dent', 'yellow') [...]... a simple template (ch20_ex27 .xml) with this schema to return customer information: Customer returns XML data like this: ... 792 SQL Server 2000 XML Sample Applications Annotate a Schema In order to use XPath and Updategrams, you must know both the relational design and the XML shape In our case, we have no XML schema, so we must create one There are tools available, such as the XML View Mapper, that facilitate creating schemas from existing databases The XML View Mapper is available from Microsoft's XML Developer Center... FOR XML AUTO or customers with their purchases: SELECT * FROM Customers JOIN Orders ON Customers.Cid=Orders.Cid FOR XML AUTO For most simple applications, this approach works well When additional control over the XML shape beyond that provided by FOR XML AUTO is required, EXPLICIT mode can be used to obtain whatever XML shape is needed See Chapter 14 for details on FOR XML EXPLICIT However, FOR XML. .. the following code (ch20_ex31.sql): INSERT INTO Orders VALUES('1999 -10- 04', '1999 -10- 04', 'ad', 2, 1.75) INSERT INTO Orders VALUES('1999 -10- 19', '1999 -10- 23', 'ad', 5, 1.50) INSERT INTO Orders VALUES('1999 -10- 25', '1999 -10- 26', 'ad', 15, 1.00) And then execute the template with this XSL named ch20_ex32.xsl: white INSERT INTO Customers VALUES (@id, @name, @color) Now that you've created a Customer, you might like to view the customer data Using FOR XML, it is easy to create XML. .. using an OpenXML statement like this (ch20_ex24.sql): DECLARE @idoc int EXEC sp _xml_ preparedocument @idoc OUTPUT, ' ' INSERT INTO NEWS SELECT * FROM OpenXML(@idoc, '/NewsStream/Story', 2) WITH (Date datetime './Date', Headline nvarchar (100 ) './Title', Story ntext './Text') Each XPath in the WITH clause selects some XML node relative to the row pattern used in the OpenXML statement... ordered by date, using the following template (ch20_ex24 .xml) : SELECT * FROM News ORDER BY Date DESC FOR XML AUTO, ELEMENTS; SELECT * FROM Purchases ORDER BY Date DESC FOR XML AUTO; where ch20_ex24.xsl is: . objXML=Server.CreateObject("MSXML2.DomDocument") objXML.async=False objXML.Load("http://localhost/northwind/Template/Ch20_ex16 .xml? eid=" & EmpID) set objEmployee=objXML.documentElement.childNodes.Item(0) '. as the XML View Mapper, that facilitate creating schemas from existing databases. The XML View Mapper is available from Microsoft's XML Developer Center at http://msdn.microsoft.com /xml. For. attributes: <Schema xmlns="urn:schemas-microsoft-com :xml- data" xmlns:dt="urn:schemas-microsoft-com:datatypes" xmlns:sql="urn:schemas-microsoft-com :xml- sql"> <ElementType

Ngày đăng: 13/08/2014, 12:21

Xem thêm: Professional XML Databases phần 10 pptx

TỪ KHÓA LIÊN QUAN