sqlserver使用clr调用ajax,在数据库内请求外部链接
sqlserver使用clr调用ajax,在数据库内请求外部链接
2019年09月11日 14:52:48 文盲老顾 阅读数 12 文章标签: clrajax外部链接sql函数 更多
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/superwfei/article/details/100735416
第一步:使用vs新建一个类库项目,编写clr程序集
-
using Microsoft.SqlServer.Server; -
using System; -
using System.Collections; -
using System.Data.SqlTypes; -
using System.Diagnostics.CodeAnalysis; -
using System.IO; -
using System.IO.Compression; -
using System.Net; -
using System.Text; -
using System.Text.RegularExpressions; -
internal class AjaxResult -
{ -
private int _statusCode; -
private string _url; -
private string _html; -
public string Url -
{ -
get -
{ -
return _url; -
} -
} -
public string Html -
{ -
get -
{ -
return _html; -
} -
} -
public int StatusCode -
{ -
get -
{ -
return _statusCode; -
} -
} -
public AjaxResult(string url, string html, int statusCode) -
{ -
_url = url; -
_html = html; -
_statusCode = statusCode; -
} -
} -
internal class AjaxIterator : IEnumerable -
{ -
private string _url; -
private string _method; -
private string _arguments; -
public AjaxIterator(string url, string method, string arguments) -
{ -
_url = url; -
_method = method; -
_arguments = arguments; -
} -
public IEnumerator GetEnumerator() -
{ -
Ajax ajax = new Ajax(); -
ajax.Http(_url, _method.ToLower(), _arguments); -
string url = ajax.CurrentUrl; -
string html = ajax.Result; -
int statusCode = (int)ajax.StatusCode; -
yield return new AjaxResult(url, html, statusCode); -
} -
} -
public static partial class ajax -
{ -
[SqlFunction(FillRowMethodName = "FillAjaxRow", TableDefinition = "url nvarchar(500),html nvarchar(max),statusCode int")] -
public static IEnumerable Http(SqlString url, SqlString method, SqlString arguments) -
{ -
return new AjaxIterator(url.Value, method.Value, arguments.Value); -
} -
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters")] -
public static void FillAjaxRow(object data, out SqlString url, out SqlString html, out SqlInt32 statusCode) -
{ -
AjaxResult node = (AjaxResult)data; -
url = new SqlString(node.Url); -
html = new SqlString(node.Html); -
statusCode = new SqlInt32(node.StatusCode); -
} -
} -
public class Ajax -
{ -
private string _url = string.Empty; -
private string _result = ""; -
private HttpStatusCode hsc = HttpStatusCode.OK; -
public string CurrentUrl -
{ -
get -
{ -
return _url; -
} -
} -
public string Result -
{ -
get -
{ -
return _result; -
} -
} -
public HttpStatusCode StatusCode -
{ -
get -
{ -
return hsc; -
} -
} -
private Encoding GetEncoding(string html) -
{ -
if (Regex.IsMatch(html, @"(?<=<meta(?!\w)[^<>]*?)charset\s*=", RegexOptions.IgnoreCase)) -
{ -
string c = Regex.Match(html, @"(?<=<meta(?!\w)[^<>]*?charset\s*=\s*['""]?(?!['""]))\w[^\s'""/<>]*", RegexOptions.IgnoreCase).Value; -
try -
{ -
Encoding en = Encoding.GetEncoding(Regex.Match(html, @"(?<=<meta(?!\w)[^<>]*?charset\s*=\s*['""]?(?!['""]))\w[^\s'""/<>]*", RegexOptions.IgnoreCase).Value); -
return en; -
} -
catch -
{ -
return null; -
} -
} -
else -
{ -
return null; -
} -
} -
public void Http(string url, string method, string QueryString) -
{ -
string full_url = (("get" == method) ? ((QueryString.Length > 0) ? ((url.IndexOf("?") > 0) ? (url + "&" + QueryString) : (url + "?" + QueryString)) : url) : url); -
ServicePointManager.Expect100Continue = false; -
ServicePointManager.DefaultConnectionLimit = Int32.MaxValue; -
string html = ""; -
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(full_url); -
http.AllowAutoRedirect = true; -
http.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0"; -
http.Accept = "*/*"; -
http.KeepAlive = false; -
http.Headers.Add("Accept-Encoding", "gzip, deflate"); -
_url = url; -
if (method == "post") -
{ -
http.Method = "POST"; -
http.Accept = "application/json, text/javascript, */*"; -
http.KeepAlive = true; -
byte[] pd = null; -
pd = new UTF8Encoding().GetBytes(QueryString); -
try -
{ -
http.ContentType = "application/x-www-form-urlencoded"; -
http.ContentLength = pd.Length; -
Stream ps = http.GetRequestStream(); -
ps.Write(pd, 0, pd.Length); -
ps.Close(); -
ps.Dispose(); -
} -
catch (Exception ex) -
{ -
_result = ex.Message; -
hsc = HttpStatusCode.BadRequest; -
return; -
} -
} -
try -
{ -
HttpWebResponse hwr = (HttpWebResponse)http.GetResponse(); -
hsc = hwr.StatusCode; -
Stream s = hwr.GetResponseStream(); -
MemoryStream ms = new MemoryStream(); -
string contentType = "normal"; -
if (hwr.Headers.GetValues("Content-Encoding") != null) -
{ -
string[] encd = hwr.Headers.GetValues("Content-Encoding"); -
for (int i = 0; i < encd.Length; i++) -
{ -
if (encd[i] == "gzip") -
{ -
contentType = "gzip"; -
break; -
} -
if (encd[i] == "deflate") -
{ -
contentType = "deflate"; -
break; -
} -
} -
} -
switch (contentType) -
{ -
case "deflate": -
DeflateStream ds = new DeflateStream(s, CompressionMode.Decompress); -
ds.CopyTo(ms); -
ds.Close(); -
ds.Dispose(); -
break; -
case "gzip": -
GZipStream g = new GZipStream(s, CompressionMode.Decompress); -
g.CopyTo(ms); -
g.Close(); -
g.Dispose(); -
break; -
default: -
s.CopyTo(ms); -
break; -
} -
s.Close(); -
s.Dispose(); -
byte[] bt = ms.ToArray(); -
ms.Close(); -
ms.Dispose(); -
html = Encoding.UTF8.GetString(bt); -
Encoding en_test = GetEncoding(html); -
if (en_test != null && en_test != Encoding.UTF8) -
{ -
html = en_test.GetString(bt); -
} -
_result = html; -
hwr.Close(); -
} -
catch (WebException ex) -
{ -
if (ex.Response == null) -
{ -
hsc = HttpStatusCode.BadRequest; -
_result = ex.Message; -
return; -
} -
hsc = ((HttpWebResponse)ex.Response).StatusCode; -
_result = ex.Message; -
} -
} -
}
在这个类库随便命名了,编写好之后生成或发布
第二步:导入程序集

在sql server management studio里,找到你要操作的数据库 -> 可编程性 -> 程序集 -> 鼠标右键 -> 新建程序集
弹出上图所示的对话框,点浏览选择之前生成的dll文件
第三步:创建一个自定义函数,调用clr程序集
-
CREATE FUNCTION [dbo].[Ajax](@url [nvarchar](max), @method [nvarchar](max), @arguments [nvarchar](max)) -
RETURNS TABLE ( -
[url] [nvarchar](500) NULL, -
[html] [nvarchar](max) NULL, -
[statusCode] [int] NULL -
) WITH EXECUTE AS CALLER -
AS -
EXTERNAL NAME [clr.ajax].[ajax].[Http]
这里,external name 之后的三个数据分别是[clr类库项目名].[clr类名].[方法名]
如图所示,我创建的clr项目名是clr.ajax,所以生成的dll是clr.ajax.dll,引用的方法就是[clr.ajax].[ajax].[Http]
第四步:设置数据库权限,允许进行外部访问
-
-- 设置clr enabled允许调用clr程序 -
sp_configure 'clr enabled',1 -
go -
reconfigure -
go -
-- 设置数据库允许方位外部 -
alter database [dbname] set trustworthy on -
go -
-- 修改程序集的设置,将权限集设置为外部访问 -
-- 通过sqlserver management studio的界面修改
这里的dbname就是你之前导入程序集的数据库了
第五步:使用自定义函数访问外部链接

自定义函数有三个参数,第一个参数是url,第二个是method,也就是谓词,比如get、post,第三个是参数集,上图已有示例了
如果使用过程中报错,请参考SQL Server 2005 CLR 调用Web Service需要注意的几个问题
----------------------------------
Hmm.....写这么个clr,可不是为了让数据库去玩采集,是为了偷懒!
什么时候用数据库去ajax呢?举几个例子:
静态页网站,当数据库更新后,用触发器或队列调用更新静态页的程序
第三方设置,当本地数据库修改设置后,同步到第三方时
token更新等
注意,可千万别再数据库里玩批量采集哦

浙公网安备 33010602011771号