• sqlserver使用clr调用ajax,在数据库内请求外部链接


    sqlserver使用clr调用ajax,在数据库内请求外部链接

    2019年09月11日 14:52:48 文盲老顾 阅读数 12 文章标签: clrajax外部链接sql函数 更多

    分类专栏: .net clr sql

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    本文链接:https://blog.csdn.net/superwfei/article/details/100735416

    第一步:使用vs新建一个类库项目,编写clr程序集

    
     
    1. using Microsoft.SqlServer.Server;

    2. using System;

    3. using System.Collections;

    4. using System.Data.SqlTypes;

    5. using System.Diagnostics.CodeAnalysis;

    6. using System.IO;

    7. using System.IO.Compression;

    8. using System.Net;

    9. using System.Text;

    10. using System.Text.RegularExpressions;

    11.  
    12. internal class AjaxResult

    13. {

    14. private int _statusCode;

    15. private string _url;

    16. private string _html;

    17. public string Url

    18. {

    19. get

    20. {

    21. return _url;

    22. }

    23. }

    24. public string Html

    25. {

    26. get

    27. {

    28. return _html;

    29. }

    30. }

    31. public int StatusCode

    32. {

    33. get

    34. {

    35. return _statusCode;

    36. }

    37. }

    38. public AjaxResult(string url, string html, int statusCode)

    39. {

    40. _url = url;

    41. _html = html;

    42. _statusCode = statusCode;

    43. }

    44. }

    45. internal class AjaxIterator : IEnumerable

    46. {

    47. private string _url;

    48. private string _method;

    49. private string _arguments;

    50. public AjaxIterator(string url, string method, string arguments)

    51. {

    52. _url = url;

    53. _method = method;

    54. _arguments = arguments;

    55. }

    56. public IEnumerator GetEnumerator()

    57. {

    58. Ajax ajax = new Ajax();

    59. ajax.Http(_url, _method.ToLower(), _arguments);

    60. string url = ajax.CurrentUrl;

    61. string html = ajax.Result;

    62. int statusCode = (int)ajax.StatusCode;

    63. yield return new AjaxResult(url, html, statusCode);

    64. }

    65. }

    66. public static partial class ajax

    67. {

    68. [SqlFunction(FillRowMethodName = "FillAjaxRow", TableDefinition = "url nvarchar(500),html nvarchar(max),statusCode int")]

    69. public static IEnumerable Http(SqlString url, SqlString method, SqlString arguments)

    70. {

    71. return new AjaxIterator(url.Value, method.Value, arguments.Value);

    72. }

    73. [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters")]

    74. public static void FillAjaxRow(object data, out SqlString url, out SqlString html, out SqlInt32 statusCode)

    75. {

    76. AjaxResult node = (AjaxResult)data;

    77. url = new SqlString(node.Url);

    78. html = new SqlString(node.Html);

    79. statusCode = new SqlInt32(node.StatusCode);

    80. }

    81. }

    82. public class Ajax

    83. {

    84. private string _url = string.Empty;

    85. private string _result = "";

    86. private HttpStatusCode hsc = HttpStatusCode.OK;

    87. public string CurrentUrl

    88. {

    89. get

    90. {

    91. return _url;

    92. }

    93. }

    94. public string Result

    95. {

    96. get

    97. {

    98. return _result;

    99. }

    100. }

    101. public HttpStatusCode StatusCode

    102. {

    103. get

    104. {

    105. return hsc;

    106. }

    107. }

    108. private Encoding GetEncoding(string html)

    109. {

    110. if (Regex.IsMatch(html, @"(?<=<meta(?!\w)[^<>]*?)charset\s*=", RegexOptions.IgnoreCase))

    111. {

    112. string c = Regex.Match(html, @"(?<=<meta(?!\w)[^<>]*?charset\s*=\s*['""]?(?!['""]))\w[^\s'""/<>]*", RegexOptions.IgnoreCase).Value;

    113. try

    114. {

    115. Encoding en = Encoding.GetEncoding(Regex.Match(html, @"(?<=<meta(?!\w)[^<>]*?charset\s*=\s*['""]?(?!['""]))\w[^\s'""/<>]*", RegexOptions.IgnoreCase).Value);

    116. return en;

    117. }

    118. catch

    119. {

    120. return null;

    121. }

    122. }

    123. else

    124. {

    125. return null;

    126. }

    127. }

    128. public void Http(string url, string method, string QueryString)

    129. {

    130. string full_url = (("get" == method) ? ((QueryString.Length > 0) ? ((url.IndexOf("?") > 0) ? (url + "&" + QueryString) : (url + "?" + QueryString)) : url) : url);

    131. ServicePointManager.Expect100Continue = false;

    132. ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;

    133. string html = "";

    134. HttpWebRequest http = (HttpWebRequest)WebRequest.Create(full_url);

    135. http.AllowAutoRedirect = true;

    136. http.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0";

    137. http.Accept = "*/*";

    138. http.KeepAlive = false;

    139. http.Headers.Add("Accept-Encoding", "gzip, deflate");

    140. _url = url;

    141. if (method == "post")

    142. {

    143. http.Method = "POST";

    144. http.Accept = "application/json, text/javascript, */*";

    145. http.KeepAlive = true;

    146. byte[] pd = null;

    147. pd = new UTF8Encoding().GetBytes(QueryString);

    148. try

    149. {

    150. http.ContentType = "application/x-www-form-urlencoded";

    151. http.ContentLength = pd.Length;

    152. Stream ps = http.GetRequestStream();

    153. ps.Write(pd, 0, pd.Length);

    154. ps.Close();

    155. ps.Dispose();

    156. }

    157. catch (Exception ex)

    158. {

    159. _result = ex.Message;

    160. hsc = HttpStatusCode.BadRequest;

    161. return;

    162. }

    163. }

    164. try

    165. {

    166. HttpWebResponse hwr = (HttpWebResponse)http.GetResponse();

    167. hsc = hwr.StatusCode;

    168. Stream s = hwr.GetResponseStream();

    169. MemoryStream ms = new MemoryStream();

    170. string contentType = "normal";

    171. if (hwr.Headers.GetValues("Content-Encoding") != null)

    172. {

    173. string[] encd = hwr.Headers.GetValues("Content-Encoding");

    174. for (int i = 0; i < encd.Length; i++)

    175. {

    176. if (encd[i] == "gzip")

    177. {

    178. contentType = "gzip";

    179. break;

    180. }

    181. if (encd[i] == "deflate")

    182. {

    183. contentType = "deflate";

    184. break;

    185. }

    186. }

    187. }

    188. switch (contentType)

    189. {

    190. case "deflate":

    191. DeflateStream ds = new DeflateStream(s, CompressionMode.Decompress);

    192. ds.CopyTo(ms);

    193. ds.Close();

    194. ds.Dispose();

    195. break;

    196. case "gzip":

    197. GZipStream g = new GZipStream(s, CompressionMode.Decompress);

    198. g.CopyTo(ms);

    199. g.Close();

    200. g.Dispose();

    201. break;

    202. default:

    203. s.CopyTo(ms);

    204. break;

    205. }

    206. s.Close();

    207. s.Dispose();

    208. byte[] bt = ms.ToArray();

    209. ms.Close();

    210. ms.Dispose();

    211. html = Encoding.UTF8.GetString(bt);

    212. Encoding en_test = GetEncoding(html);

    213. if (en_test != null && en_test != Encoding.UTF8)

    214. {

    215. html = en_test.GetString(bt);

    216. }

    217. _result = html;

    218. hwr.Close();

    219. }

    220. catch (WebException ex)

    221. {

    222. if (ex.Response == null)

    223. {

    224. hsc = HttpStatusCode.BadRequest;

    225. _result = ex.Message;

    226. return;

    227. }

    228. hsc = ((HttpWebResponse)ex.Response).StatusCode;

    229. _result = ex.Message;

    230. }

    231. }

    232. }

    在这个类库随便命名了,编写好之后生成或发布

    第二步:导入程序集

    在sql server management studio里,找到你要操作的数据库 -> 可编程性 -> 程序集 -> 鼠标右键 -> 新建程序集

    弹出上图所示的对话框,点浏览选择之前生成的dll文件

    第三步:创建一个自定义函数,调用clr程序集

    
     
    1. CREATE FUNCTION [dbo].[Ajax](@url [nvarchar](max), @method [nvarchar](max), @arguments [nvarchar](max))

    2. RETURNS TABLE (

    3. [url] [nvarchar](500) NULL,

    4. [html] [nvarchar](max) NULL,

    5. [statusCode] [int] NULL

    6. ) WITH EXECUTE AS CALLER

    7. AS

    8. EXTERNAL NAME [clr.ajax].[ajax].[Http]

    这里,external name 之后的三个数据分别是[clr类库项目名].[clr类名].[方法名]

    如图所示,我创建的clr项目名是clr.ajax,所以生成的dll是clr.ajax.dll,引用的方法就是[clr.ajax].[ajax].[Http]

    第四步:设置数据库权限,允许进行外部访问

    
     
    1. -- 设置clr enabled允许调用clr程序

    2. sp_configure 'clr enabled',1

    3. go

    4. reconfigure

    5. go

    6. -- 设置数据库允许方位外部

    7. alter database [dbname] set trustworthy on

    8. go

    9. -- 修改程序集的设置,将权限集设置为外部访问

    10. -- 通过sqlserver management studio的界面修改

    这里的dbname就是你之前导入程序集的数据库了

    第五步:使用自定义函数访问外部链接

    自定义函数有三个参数,第一个参数是url,第二个是method,也就是谓词,比如get、post,第三个是参数集,上图已有示例了

    如果使用过程中报错,请参考SQL Server 2005 CLR 调用Web Service需要注意的几个问题

    ----------------------------------

    Hmm.....写这么个clr,可不是为了让数据库去玩采集,是为了偷懒!

    什么时候用数据库去ajax呢?举几个例子:

    静态页网站,当数据库更新后,用触发器或队列调用更新静态页的程序

    第三方设置,当本地数据库修改设置后,同步到第三方时

    token更新等

    注意,可千万别再数据库里玩批量采集哦

  • 相关阅读:
    寒假作业1实践题
    寒假作业1问答题
    (1.21)思考题
    [golang note] 匿名组合
    [golang note] 类型系统
    [golang note] 错误处理
    [golang note] 函数定义
    [golang note] 流程控制
    [golang note] 内建类型
    [golang note] 数组切片
  • 原文地址:https://www.cnblogs.com/grj001/p/12224004.html
Copyright © 2020-2023  润新知