在 SQL 2008 CLR UDF 中使用 HttpWebrequest 解决不稳定行为

Posted

技术标签:

【中文标题】在 SQL 2008 CLR UDF 中使用 HttpWebrequest 解决不稳定行为【英文标题】:Solving Erratic Behavior with HttpWebrequest in SQL 2008 CLR UDF 【发布时间】:2009-03-21 02:22:57 【问题描述】:

我们目前正在尝试实施 sql server 2008 udf 来扩展缩短的 url。我们让它对大多数主要的 URL 缩短服务都非常有效。但是,在看似随机的时间,它会“挂起”并拒绝针对某个域(例如 bit.ly)工作,而随后对其他服务(例如 tinyurl.com)的调用将继续成功。

我们最初认为这是由于 url 缩短提供程序的某种阻塞,但停止并重新启动 dbserver 服务会导致后续请求成功。会不会是 SQL 服务器以某种方式汇集了传出的 http 连接?

这是代码...

using System;
using System.Data;
using System.Net;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions

    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString UrlExpander(string url)
    
            // Set up the Webrequest
            HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(url);
            try
            

            // Set autoredirect off so the redirected URL will not be loaded
            wr.AllowAutoRedirect = false;

            // Get the response
            HttpWebResponse wresp = (HttpWebResponse)wr.GetResponse();

            return new SqlString(wresp.Headers["Location"].ToString());
        
        catch (Exception ex)
        
            wr.Abort();
            throw ex;

        


    
;

【问题讨论】:

与您的问题无关,但您不应该有任何问题(Exception ex)。相反,您应该简单地将 wr.Abort() 放在 finally 块中。 是的,在大多数情况下确实如此,但考虑到这个特定 UDF 的性质,我们真的不希望异常冒泡到 TSQL 级别。上面代码中的重新抛出是实验性的,看看这是否有助于服务器恢复。在我们看来,要么它工作,要么它返回 null。谢谢。 【参考方案1】:

你缺少 wresp.Close()。

【讨论】:

【参考方案2】:

鉴于 Jesse 的反馈以及我们希望拥有一个返回正确扩展的 url 或 NULL 的函数,我们提出了以下方法,它似乎可以处理 1000 多个缩小的 URL,而没有进一步的问题:

[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString UrlExpander(string url)

    // Set up the Webrequest
    try
    
        HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(url);
        try
        
            // Set autoredirect off so the redirected URL will not be loaded
            wr.AllowAutoRedirect = false;

            // Get the response
            HttpWebResponse wresp = (HttpWebResponse)wr.GetResponse();
            wresp.Close();

            if (wresp != null)
                return new SqlString(wresp.Headers["Location"].ToString());
        
        finally
        
            if (wr != null)
                wr.Abort();
        
    
    catch
    
    

    return null;


【讨论】:

以上是关于在 SQL 2008 CLR UDF 中使用 HttpWebrequest 解决不稳定行为的主要内容,如果未能解决你的问题,请参考以下文章

SQL CLR标量UDF中的DES解密不起作用

SQL Server 2008 CLR 聚合函数

将 UDF 与 SQL Query 一起使用时出错

如何在 SQL CLR 中添加 Linq 支持

SQL Server 2008 - UDF 参数类型和返回类型

SQL Server 2008 T-SQL UDF Split() 剪裁