操作 UDT 数据

Transact-SQL 没有为在对用户定义类型 (UDT) 列中的数据进行修改时所使用的 INSERT、UPDATE 或 DELETE 语句提供专用语法。Transact-SQL CAST 或 CONVERT 函数用于将本机数据类型转换为 UDT 类型。

在 UDT 列中插入数据

以下 Transact-SQL 语句将三行示例数据插入 Points 表中。Point 数据类型由作为 UDT 属性公开的 X 和 Y 整数值组成。必须使用 CAST 或 CONVERT 函数,才能将以逗号分隔的 X 和 Y 值转换为 Point 类型。前两个语句使用 CONVERT 函数将字符串值转换为 Point 类型,第三个语句使用 CAST 函数:

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 语句选择 UDT 的二进制值。

SELECT ID, PointValue FROM dbo.Points

若要查看按可读格式显示的输出,请调用 Point UDT 的 ToString 方法,该方法可以将值转换为其字符串表示形式。

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

这将产生以下结果:

IDPointValue
----------
13,4
21,5
31,99

还可以使用 Transact-SQL CAST 和 CONVERT 函数以取得相同结果。

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

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

Point UDT 将其 X 和 Y 坐标作为属性公开,然后您可以分别选择这些属性。以下 Transact-SQL 语句将分别选择 X 和 Y 坐标:

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

X 和 Y 属性将返回整数值,该值在结果集中显示。

IDxValyVal
----------
134
215
3199

使用变量

可以通过使用 DECLARE 语句将变量分配给 UDT 类型来使用变量。以下语句使用 Transact-SQL SET 语句执行赋值,并通过对变量调用 UDT 的 ToString 方法来显示结果:

DECLARE @PointValue Point;
SET @PointValue = (SELECT PointValue FROM dbo.Points
    WHERE ID = 2);
SELECT @PointValue.ToString() AS PointValue;

结果集显示变量值:

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

以下 Transact-SQL 语句使用 SELECT 而不是 SET 进行变量赋值,可取得相同结果:

DECLARE @PointValue Point;
SELECT @PointValue = PointValue FROM dbo.Points
    WHERE ID = 2;
SELECT @PointValue.ToString() AS PointValue;

使用 SELECT 和使用 SET 进行变量赋值的差异是 SELECT 允许在一个 SELECT 语句中为多个变量赋值,而 SET 语法则要求每次变量赋值都要有自己的 SET 语句。

比较数据

如果已在定义类时将 IsByteOrdered 属性设置为 true,则可以在 UDT 中使用比较运算符进行值的比较。有关详细信息,请参阅创建用户定义类型

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

如果值本身是可比较的,则可以比较 UDT 的内部值,而无需考虑 IsByteOrdered 设置。以下 Transact-SQL 语句选择 X 大于 Y 的行:

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

还可以对变量使用比较运算符,如搜索匹配的 PointValue 的查询所示。

DECLARE @ComparePoint Point;
SET @ComparePoint = CONVERT(Point, '3,4');
SELECT ID, PointValue.ToString() AS MatchingPoint 
FROM dbo.Points
WHERE PointValue = @ComparePoint;

调用 UDT 方法

还可以在 Transact-SQL 中调用在 UDT 中定义的方法。Point 类包含三个方法:Distance、DistanceFrom 和 DistanceFromXY。有关定义这三个方法的代码列表,请参阅用户定义类型编码

以下 Transact-SQL 语句调用 PointValue.Distance 方法:

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

结果在 Distance 列中显示:

IDXYDistance
------------------------
1345
2155.09901951359278
319999.0050503762308

DistanceFrom 方法接受 Point 数据类型的参数,并显示从指定点到 PointValue 的距离:

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

结果将针对表中的每一行显示 DistanceFrom 方法的结果:

ID PntDistanceFromPoint
---------------------
13,495.0210502993942
21,594
31,990

DistanceFromXY 方法逐个接受各点作为参数:

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

结果集与 DistanceFrom 方法相同。

更新 UDT 列中的数据

若要更新 UDT 列中的数据,请使用 Transact-SQL UPDATE 语句。还可以使用 UDT 的方法以更新对象的状态。以下 Transact-SQL 语句更新表中的单个行:

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

还可以单独更新 UDT 元素。以下 Transact-SQL 语句仅更新 Y 坐标:

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

如果已在将字节顺序设置为 true 的情况下定义 UDT,则 Transact-SQL 可以通过 WHERE 子句计算 UDT 列。

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

更新限制

无法使用 Transact-SQL 一次更新多个属性。例如,以下 UPDATE 语句将失败并返回错误,因为无法在一个 UDATE 语句中两次使用相同的列名称。

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

若要分别更新每个点,需要在 Point UDT 程序集中创建赋值函数方法。然后,可以在 Transact-SQL UPDATE 语句中调用赋值函数方法以更新对象,如下所示:

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

删除 UDT 列中的数据

若要删除 UDT 中的数据,请使用 Transact-SQL DELETE 语句。以下语句删除该表中与 WHERE 子句中指定的条件匹配的所有行。如果在 DELETE 语句中省略 WHERE 子句,将删除表中所有行。

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

如果要删除 UDT 列中的值而不改变其他行值,请使用 UPDATE 语句。下面的示例将 PointValue 设置为 Null:

UPDATE dbo.Points
SET PointValue = null
WHERE ID = 2