演练:调试 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 用户定义的表值函数
在一个新的 SQL CLR 项目中,建立一个到数据库的连接。 有关更多信息,请参见How to: Connect to a Database。
使用下面第一个示例部分中的代码创建一个新的函数,并将其命名为“TableOfPrimes.cs”。 有关更多信息,请参见How to: Develop with the SQL Server Project Type。
添加一个对该功能进行测试的脚本,方法是,在 SELECT 语句中包括该脚本。 在**“解决方案资源管理器”中,右击“TestScripts”目录,单击“添加测试脚本”,然后插入下面的第二个示例部分中的代码。 以“TestPrime.sql”名称保存文件。 右击该文件名,然后单击“设置为默认调试脚本”**。
在 TableOfPrimes.cs 中设置断点,然后在**“调试”菜单上,单击“启动”**以对该项目进行编译、部署和单元测试。 当用黄色箭头表示的指令指针出现在一个断点上时,说明正在调试 SQL CLR 代码。
尝试不同的调试功能。
在**“调试”菜单上重复单击“单步执行”**,观察逐行执行函数的情况。
逐句通过该函数时,可以使用**“局部变量”和“监视”**窗口观察不同成员的值。
再次单击**“继续”**完成函数调试。
在**“输出”窗口中,从“显示输出来源”下拉列表中选择“数据库输出”**,您可观察到执行 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