Manipulate user-defined type (UDT) data

Applies to: SQL Server

Transact-SQL provides no specialized syntax for INSERT, UPDATE, or DELETE statements when modifying data in user-defined type (UDT) columns. The Transact-SQL CAST or CONVERT functions are used to cast native data types to the UDT type.

Insert data in a UDT column

The following Transact-SQL statements insert three rows of sample data into the Points table. The Point data type consists of X and Y integer values that are exposed as properties of the UDT. You must use either the CAST or CONVERT function to cast the comma-delimited X and Y values to the Point type. The first two statements use the CONVERT function to convert a string value to the Point type, and the third statement uses the CAST function:

INSERT INTO dbo.Points (PointValue)
VALUES (CONVERT (Point, '3,4'));

INSERT INTO dbo.Points (PointValue)
VALUES (CONVERT (Point, '1,5'));

INSERT INTO dbo.Points (PointValue)
VALUES (CAST ('1,99' AS Point));

Select data

The following SELECT statement selects the binary value of the UDT.

SELECT ID, PointValue
FROM dbo.Points;

To see the output displayed in a readable format, call the ToString method of the Point UDT, which converts the value to its string representation.

SELECT ID, PointValue.ToString() AS PointValue
FROM dbo.Points;

Here's the result set.

ID PointValue
-- ----------
 1 3,4
 2 1,5
 3 1,99

You can also use the Transact-SQL CAST and CONVERT functions to achieve the same results.

SELECT ID, CAST (PointValue AS VARCHAR)
FROM dbo.Points;

SELECT ID, CONVERT (VARCHAR, PointValue)
FROM dbo.Points;

The Point UDT exposes its X and Y coordinates as properties, which you can then select individually. The following Transact-SQL statement selects the X and Y coordinates separately:

SELECT ID,
       PointValue.X AS xVal,
       PointValue.Y AS yVal
FROM dbo.Points;

The X and Y properties return an integer value, which is displayed in the result set.

ID xVal yVal
-- ---- ----
 1    3    4
 2    1    5
 3    1   99

Work with variables

You can work with variables using the DECLARE statement to assign a variable to a UDT type. The following statements assign a value using the Transact-SQL SET statement and display the results by calling the UDT's ToString method on the variable:

DECLARE @PointValue AS Point;

SET @PointValue = (SELECT PointValue
                   FROM dbo.Points
                   WHERE ID = 2);

SELECT @PointValue.ToString() AS PointValue;

The result set displays the variable value:

PointValue
----------
-1,5

The following Transact-SQL statements achieve the same result using SELECT rather than SET for the variable assignment:

DECLARE @PointValue AS Point;

SELECT @PointValue = PointValue
FROM dbo.Points
WHERE ID = 2;

SELECT @PointValue.ToString() AS PointValue;

The difference between using SELECT and SET for variable assignment is that SELECT allows you to assign multiple variables in one SELECT statement, whereas the SET syntax requires each variable assignment to have its own SET statement.

Compare data

You can use comparison operators to compare values in your UDT if you set the IsByteOrdered property to true when defining the class. For more information, see Create user-defined types.

SELECT ID, PointValue.ToString() AS Points
FROM dbo.Points
WHERE PointValue > CONVERT (Point, '2,2');

You can compare internal values of the UDT regardless of the IsByteOrdered setting if the values themselves are comparable. The following Transact-SQL statement selects rows where X is greater than Y:

SELECT ID, PointValue.ToString() AS PointValue
FROM dbo.Points
WHERE PointValue.X < PointValue.Y;

You can also use comparison operators with variables, as shown in this query that searches for a matching PointValue.

DECLARE @ComparePoint AS Point;
SET @ComparePoint = CONVERT (Point, '3,4');

SELECT ID, PointValue.ToString() AS MatchingPoint
FROM dbo.Points
WHERE PointValue = @ComparePoint;

Invoke UDT methods

You can also invoke methods that are defined in your UDT in Transact-SQL. The Point class contains three methods, Distance, DistanceFrom, and DistanceFromXY. For the code listings defining these three methods, see Create user-defined types with ADO.NET.

The following Transact-SQL statement calls the PointValue.Distance method:

SELECT ID,
       PointValue.X AS [Point.X],
       PointValue.Y AS [Point.Y],
       PointValue.Distance() AS DistanceFromZero
FROM dbo.Points;

The results are displayed in the Distance column:

ID X  Y  Distance
-- -- -- ----------------
 1  3  4                5
 2  1  5 5.09901951359278
 3  1 99 99.0050503762308

The DistanceFrom method takes an argument of Point data type, and displays the distance from the specified point to the PointValue:

SELECT ID,
       PointValue.ToString() AS Pnt,
       PointValue.DistanceFrom(CONVERT (Point, '1,99')) AS DistanceFromPoint
FROM dbo.Points;

The results display the results of the DistanceFrom method for each row in the table:

ID Pnt DistanceFromPoint
-- --- -----------------
 1 3,4  95.0210502993942
 2 1,5                94
 3 1,9                90

The DistanceFromXY method takes the points individually as arguments:

SELECT ID,
       PointValue.X AS X,
       PointValue.Y AS Y,
       PointValue.DistanceFromXY(1, 99) AS DistanceFromXY
FROM dbo.Points;

The result set is the same as the DistanceFrom method.

Update data in a UDT column

To update data in a UDT column, use the Transact-SQL UPDATE statement. You can also use a method of the UDT to update the state of the object. The following Transact-SQL statement updates a single row in the table:

UPDATE dbo.Points
SET PointValue = CAST ('1,88' AS Point)
WHERE ID = 3;

You can also update UDT elements separately. The following Transact-SQL statement updates only the Y coordinate:

UPDATE dbo.Points
SET PointValue.Y = 99
WHERE ID = 3;

If the UDT is defined with byte ordering set to true, Transact-SQL can evaluate the UDT column in a WHERE clause.

UPDATE dbo.Points
SET PointValue = '4,5'
WHERE PointValue = '3,4';

Update limitations

You can't update multiple properties at once using Transact-SQL. For example, the following UPDATE statement fails with an error because you can't use the same column name twice in one UPDATE statement.

UPDATE dbo.Points
SET PointValue.X = 5, PointValue.Y = 99
WHERE ID = 3;

To update each point individually, you would need to create a mutator method in the Point UDT assembly. You can then invoke the mutator method to update the object in a Transact-SQL UPDATE statement, as in the following example:

UPDATE dbo.Points
SET PointValue.SetXY(5, 99)
WHERE ID = 3;

Delete data in a UDT column

To delete data in a UDT, use the Transact-SQL DELETE statement. The following statement deletes all rows in the table that match the criteria specified in the WHERE clause. If you omit the WHERE clause in a DELETE statement, all rows in the table are deleted.

DELETE dbo.Points
WHERE PointValue = CAST ('1,99' AS Point);

Use the UPDATE statement if you want to remove the values in a UDT column while leaving other row values intact. This example sets the PointValue to null.

UPDATE dbo.Points
SET PointValue = NULL
WHERE ID = 2;