• Aucun résultat trouvé

Computed Columns

Dans le document SQL Server (Page 98-102)

Never let it be said that the xmldata type is not flexible. Not only is it possible to apply defaults and constraints to an xmldata type column, but the XML contained in the column can be used in creating computed columns as well.

Computed columns are virtual columns, or existing columns, that are computed from an expression or equation using one or more columns in the same table. For example, it is possible to convert the value from a string column to an xmlcolumn as follows:

CREATE TABLE Table1 ( Column1 varchar(200),

Column2 as CAST(column1 as xml) )

GO

The preceding example reads the value from column1and is used to compute the values for column2. The catch in this example is that in order for this to work, the data in column1must be well-formed XML.

It is also possible to go the other way as well, meaning you can convert xmlto a string, as follows:

CREATE TABLE Table2 ( Column1 xml,

Column2 as CAST(column1 varchar(500)) )

GO

The CASTfunction was used in both of these examples to explicitly convert one data type to another data type.

Although this is nice, the real power comes from the capability to read XML instance node values and use those values to create computed columns.

xmldata type methods cannot be used to create computed columns directly, so you must utilize other methods in the creation of computed columns, such as using UDFs to wrap the xmldata type method.

Since xmldata type methods can’t be used to create computed columns, the simple solution is to create a user-defined function that queries the value from the XML instance and then uses the function in the CREATE TABLEstatement. The first step is to create the user-defined function as follows:

CREATE FUNCTION GetNodeValue(@xmlvar xml) RETURNS int AS BEGIN

RETURN @xmlvar.value(‘(/Employee/@EmployeeID)[1]’, ‘int’) END

GO

The second step is to create the table:

CREATE TABLE Employee ( EmployeeInfo xml,

EmployeeID as dbo.GetNodeValue(EmployeeInfo) )

GO

You must specify the dboaccount when specifying the user-defined function during the table creation statement because if it is left off, SQL Server does not recognize it as a built-in function and generates an error.

The next step is to insert the XML data into the table (the EmployeeInfo column):

INSERT INTO Employee (EmployeeInfo)

VALUES (‘<Employee EmployeeID=”10”><FirstName>Robin</FirstName></Employee>’) GO

Now query the Employee table and review the results. The results should look like Figure 4-11.

Figure 4-11

In the previous example, the user-defined function was created and used in the CREATE TABLE state-ment as the computed column for the second column (EmployeeID). The user-defined function uses the value()method to query the XML instance for a specific value, in this case the EmployeeIDattribute of the Employeenode. When a record is inserted into the table, the user-defined function pulls the value from the XML instance and is used as the value for the EmployeeID column.

This functionality also makes it possible (and quite simple) to use the query()method to query entire XML fragments to be used for computed columns.

Modify the user-defined function as follows:

DROP FUNCTION GetElementInfo GO

CREATE FUNCTION GetElementInfo(@xmlvar xml) RETURNS xml AS BEGIN

RETURN @xmlvar.query(‘root/Employee’) END

GO

The table also needs to change a bit:

DROP TABLE Employee GO

CREATE TABLE Employee ( EmployeeInfo xml,

EmployeeID as dbo.GetElementInfo(EmployeeInfo) )

GO

The last step is to insert a row into the table with a somewhat sizable XML instance:

INSERT INTO Employee (EmployeeInfo)

VALUES (‘<root><Employee><FirstName>Robin</FirstName></Employee></root>’) GO

Query the Employee table again to view the results, as shown in Figure 4-12.

Figure 4-12

In this example, the UDF is applied to the EmployeeID column with the data type being set as the user-defined function. The UDF queries and returns the entire XML document, returning the XML document such that when the UDF is applied to the EmployeeID column and data is inserted into the EmployeeInfo table, the UDF executes and sets the value of EmployeeID column equal to what was inserted into the EmployeeInfo column. The Employee column is therefore used as a computed column using the xmldata type.

By now you should start to have a grasp on computed columns using the xmldata type column, and you can move on to other matters, such as views, which are covered in the next section.

Creating V iews

Views can be created using an xmldata type column. Since the contents of a view are based on a query, this makes it very enticing to use with the xmldata type because the view has access to all the xmldata type functionality, such as the value()and query()methods.

The following example illustrates building a view that queries an xmldata type column and uses the value()method to return values.

First, a little clean-up:

INSERT INTO Motocross (MotocrossID, MotocrossInfo) VALUES (1, ‘

After inserting the data, the next step is to create the view:

CREATE VIEW GetTeamInfo AS

SELECT MotocrossInfo.value(‘(/Motocross/Team/@Manufacturer)[1]’, ‘varchar(40)’) as Team,

MotocrossInfo.value(‘(/Motocross/Team)[1]’, ‘varchar(40)’) as Riders FROM Motocross

Now that the view is created, you can query it:

SELECT * FROM GetTeamInfo The results should look like this:

Team Riders

--- ---Yamaha Tim Ferry Chad Reed David Vuillemin

Views are a great way to filter the data coming from the xmldata type column, and other than not being able to use views in a distributed partitioned view (see the “xml data type Best Practices” and

“Limitations” sections), there are no limitations when using the xmldata type in a view.

A distributed partitioned view is a view that includes a UNION ALLoperator, where the tables defined by the UNION ALLare structured equally. However, the tables are stored as multiple tables within the same instance of SQL Server or a group of independent instances.

Dans le document SQL Server (Page 98-102)