演练:调试 SQL CLR 用户定义的类型

本主题适用于:

版本

Visual Basic

C#

C++

Web Developer

学习版

主题不适用 主题不适用 主题不适用 主题不适用

标准版

主题不适用 主题不适用 主题不适用 主题不适用

专业及团队版

主题适用 主题适用 主题适用 主题适用

本示例演示如何调试 SQL Server 公共语言运行时 (SQL CLR) 用户定义的类型。 它在 AdventureWorks 示例数据库中创建一个新的 SQL CLR 类型。 该类型随后用于表定义、INSERT 语句以及 SELECT 语句中。

如果在尝试调试 SQL CLR 对象时,显示消息“被用户取消”,您必须手动配置运行 Visual Studio 的计算机以及运行 SQL Server 的计算机。 有关更多信息,请参见如何:配置计算机以启用 Transact-SQL 和 SQL CLR 调试

提示

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。 若要更改设置,请在“工具”菜单上选择“导入和导出设置”。 有关更多信息,请参见 使用设置

调试 CLR SQL 用户定义的类型

  1. 在一个新的 SQL CLR 项目中,建立一个到 AdventureWorks 示例数据库的连接。 有关更多信息,请参见How to: Connect to a Database

  2. 使用下面第一个示例部分中的代码创建一个新的类型,并将其命名为“Point.cs”。 有关更多信息,请参见How to: Develop with the SQL Server Project Type

  3. 添加测试该类型的脚本。 在**“解决方案资源管理器”中,右击“TestScripts”目录,单击“添加测试脚本”,然后插入下面的第二个示例部分中的代码。 以“Point.sql”名称保存文件。 右击该文件名,然后单击“设置为默认调试脚本”**。

  4. 添加断点。

    1. 在**“服务器资源管理器”“类型”**文件夹中,打开“Point”。

    2. 将断点放在每个方法内,以便可以观察该类型内的控制流。

  5. 从**“调试”菜单中,选择“启动”**对该项目进行编译、部署和单元测试。 以黄色箭头表示的指令指针出现在断点上时,说明正在调试函数。

  6. 尝试不同的调试功能。

    1. 对于 Point.sql 脚本中的每条 INSERT 语句,都会执行一次 Parse 方法。 通过在**“调试”菜单上重复单击“逐语句”**,可监视该方法如何将一个用冒号分隔的数字对转换为 Point 对象。

    2. 在**“局部变量”**窗口中,打开变量 pt,它包含正在生成的当前 Point。

    3. 在文本编辑器中,双击 pt 变量以选择它。 将 pt 拖到**“监视”**窗口上的任意位置。 pt 现在就添加到受监视变量的列表中了,您就可以在生成 Point 时对该变量进行观察。

    4. 逐句通过该类几次并观察 INSERT 和 SELECT 所通过的路径之间的差异。

    5. 再次按**“继续”**完成函数调试。

示例

这是定义此示例中所使用类型的代码。 此代码创建名为 Points 的表、向其中插入行并输出表的内容。 请注意,在创建表和访问表之间不必包含批命令 GO。 实际上,Visual Studio 2005 会将 GO 解释为无效的 SQL 命令。

using System;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Runtime.Serialization;

[Serializable, SqlUserDefinedTypeAttribute(Format.Native)]
public struct Point: INullable
{
    private bool m_isNull;
    private double m_x;
    private double m_y;

    public bool IsNull {
        get { return (m_isNull); }
    }

    public override string ToString()
    {
        if (this.IsNull) { return "NULL"; }
        else { return this.m_x + ":" + this.m_y; }
    }

    public static Point Parse(SqlString s)
    {
        if (s.IsNull) { return Null; }
        else
        {
            // Parse input string here to separate out points:
            Point pt = new Point();
            string str = Convert.ToString(s);
            string[] xy = str.Split(':');

            pt.X = Convert.ToDouble(xy[0]);
            pt.Y = Convert.ToDouble(xy[1]);
            return (pt);
        }
    }

    public static Point Null
    {
        get
        {
            Point pt = new Point();
            pt. m_isNull = true;
            return (pt);
        }
    }

    public double X
    {
        get { return (this.m_x); }
        set { m_x = value; }
    }

    public double Y
    {
        get { return (this.m_y); }
        set { m_y = value; }
    }
}

这是调用此函数的测试脚本。

CREATE TABLE dbo.Points ( 
            ID int IDENTITY(1,1) PRIMARY KEY, 
            Pnt Point) 
INSERT INTO dbo.Points (Pnt) VALUES (CONVERT(Point, '3:4')) 
INSERT INTO dbo.Points (Pnt) VALUES (CONVERT(Point, '-1:5')) 
INSERT INTO dbo.Points (Pnt) VALUES (CAST ('1:99' AS Point)) 
SELECT ID, 
        Pnt.ToString() as StringPoint, 
        Pnt.X as X, 
        Pnt.Y as Y      
FROM dbo.Points

请参见

任务

如何:通过使用公共语言运行时集成创建和运行 SQL Server 用户定义的类型