演练:调试 SQL CLR 用户定义的表值函数

本主题适用于:

版本

Visual Basic

C#

C++

Web Developer

学习版

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

标准版

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

专业及团队版

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

本示例演示如何调试 SQL Server 公共语言运行时 (SQL CLR) 用户定义的表值函数 (UDF)。

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

提示

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

调试 SQL CLR 用户定义的表值函数

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

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

  3. 添加一个对该功能进行测试的脚本,方法是,在 SELECT 语句中包括该脚本。 在**“解决方案资源管理器”中,右击“TestScripts”目录,单击“添加测试脚本”,然后插入下面的第二个示例部分中的代码。 以“TestPrime.sql”名称保存文件。 右击该文件名,然后单击“设置为默认调试脚本”**。

  4. 在 TableOfPrimes.cs 中设置断点,然后在**“调试”菜单上,单击“启动”**以对该项目进行编译、部署和单元测试。 当用黄色箭头表示的指令指针出现在一个断点上时,说明正在调试 SQL CLR 代码。

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

    1. 在**“调试”菜单上重复单击“单步执行”**,观察逐行执行函数的情况。

    2. 逐句通过该函数时,可以使用**“局部变量”“监视”**窗口观察不同成员的值。

    3. 再次单击**“继续”**完成函数调试。

    4. 在**“输出”窗口中,从“显示输出来源”下拉列表中选择“数据库输出”**,您可观察到执行 TestPrimes.sql 脚本中的两个查询的结果。

示例

这是读取事件日志的代码。

using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;

public partial class UserDefinedFunctions
{
    struct primeIndex
    {
        public int n;
        public int p;
        public primeIndex(int n, int p)  
        { 
            this.n = n; this.p = p;
        }
    }

    static bool isPrime(int p)
    {
        if (p < 2) return false;
        if (p == 2) return true;
        if (p % 2 == 0) return false;
        for (int d = 3; d * d <= p; d+=2)
        {
            if (p % d == 0) return false;
        }
        return true;
    }

    static int nextPrime(int p)
    {
        int result = p + 1;
        while (!isPrime(result)) result++;
        return result;
    }

    [SqlFunction(FillRowMethodName = "Fill", TableDefinition = "n int,p int,est float")]
    public static IEnumerable TableOfPrimes(int n)
    {
        int p = 1;
        for (int i = 1; i <= n; i++)
        {
            p = nextPrime(p);
            yield return new primeIndex(i, p);
        }
    }

    private static void Fill(object source, out int n, out int p, out SqlDouble est)
    {
        primeIndex pi = (primeIndex)source;
        n = pi.n;
        p = pi.p;
        if (n <5)
            est = SqlDouble.Null;
        else
        {
            double log = Math.Log(n);
            double loglog = Math.Log(log);
            est = n * (log + loglog - 1 + loglog / log - 2 / log); 
        }
    }
}

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

SELECT n,p,est FROM dbo.TableOfPrimes(50)

SELECT TOP 10 n, p, est, est/p AS factor FROM dbo.TableOfPrimes(500) ORDER BY factor DESC

SELECT TOP 10 n, p, est, est/p AS factor FROM dbo.TableOfPrimes(1000) WHERE n>500 ORDER BY factor DESC

请参见

任务

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