0

客观的:

我们想使用执行 HTTP 请求的 .Net 3.5 使用 VB.NET 2008 编写一个 DLL

然后,我们要从 SQL Server 2005(在触发器中)调用 DLL,并向 DLL 传递一些变量并获得返回值。

我在这个过程中的位置。

我已经创建了 DLL 'HTTPDLL.dll'

资源:

Imports System
Imports System.Configuration
Imports System.Collections.Generic
Imports System.Text
Imports System.Net
Imports System.Security
Imports System.Security.Permissions
Imports System.IO
Imports Microsoft.SqlServer.Server



Public Class HTTPDLL

Public Function HTTPPost(ByVal URL As String, ByVal Content As String) As Boolean

    Dim myURL As String = Trim(URL)
    Dim mycontent As String = Trim(Content)
    Dim rawOutput As String = ""

    'Get Acces Right to web
    Dim p As New WebPermission(NetworkAccess.Connect, myURL)
    p.Assert()

    'Prepare the web Request
    Dim req As WebRequest = WebRequest.Create(myURL)
    req.Timeout = 60000
    req.Method = "POST"
    req.ContentLength = mycontent.Length
    req.ContentType = "application/x-www-form-urlencoded"

    Dim sw As New StreamWriter(req.GetRequestStream())
    sw.Write(mycontent)
    sw.Close()

    Dim resp As WebResponse = req.GetResponse()
    Dim sr As New StreamReader(resp.GetResponseStream)
    rawOutput = sr.ReadToEnd()
    sr.Close()
    Return True


End Function

Public Function Test() As Integer
    Return 1
End Function


Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long, _
ByVal lpvReserved As Long) As Boolean

    Dim s As String =     "sdfghjkolihdgjkhgiueghkyhekygigdjhgfkhsgdkhfgksjdhgkjshdgfkjhsgdkjfhgkshdgfkjhgskjdhgfkjhsdgkfhgskjdhfgkjsdhgfkshdgfkhgsdkfhgksdhfgkshdgfkshdgfkjhsgdkfhgskdhfgksjdhgfkjshgdfkhsgdkfhgskdhfgkshgdfkjhgskdjg"
    s &= "kjhdgjkshkdjfhklsjdhfljhgkhvbfiuvbli klrfgliu ghliebliuhdflivbdkljhgljuhfvliuhdf"
    Return True

End Function

End Class

我已将 DLL 放在 SQL Server c:/Windows/System 文件夹中

我已经加载了这些程序集

HelloWorld System.Core System.XML.Linq

使用这些命令

EXEC sp_configure 'show advanced options' , '1';
go
reconfigure
go

EXEC sp_configure 'clr enabled' , '1'
go

sp_configure 'Ole Automation Procedures', '1'
GO 
RECONFIGURE

-- Turn advanced options back off
EXEC sp_configure 'show advanced options' , '0';
go
reconfigure
GO
-- assembly style
ALTER DATABASE master SET TRUSTWORTHY ON
GO

CREATE ASSEMBLY [System.Core]
AUTHORIZATION [dbo]
FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
WITH PERMISSION_SET = UNSAFE
GO

CREATE ASSEMBLY [System.Xml.Linq]
AUTHORIZATION [dbo]
FROM 'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll'
WITH PERMISSION_SET = UNSAFE
GO

create assembly HelloWorld from 'C:\WINDOWS\system\HTTPDLL.dll'
with permission_set = safe
GO

然后我添加了扩展程序

USE [master]
GO
/****** Object:  ExtendedStoredProcedure [dbo].[HTTPDLL]    Script Date: 02/03/2010 11:45:28 ******/
EXEC dbo.sp_addextendedproc N'HTTPDLL', 'C:\WINDOWS\system\HTTPDLL.dll'

(此时我不确定为什么或是否需要添加程序集,因为它直接引用了 Dll。)

我需要解决的问题。我现在想调用 DLL 的(扩展过程)HTTPPost 函数

我尝试过的 exec HTTPPost "Msg 17750, Level 16, State 0, Procedure HTTPPost, Line 1 无法加载 DLL HelloWorld 或其引用的 DLL 之一。原因:126(找不到指定的模块。)。 "

exec HelloWorld.HTTPPost 'http://www.somewebsite.com',''

“消息 2812,级别 16,状态 62,第 1 行找不到存储过程 'HelloWorld.HTTPPost'。”

我需要什么:如果您可以查看我的实施,看看我是否正确设置了所有内容,并告诉我(请提供示例)如何正确调用该 DLL,向其发送变量并捕获其返回值。我将不胜感激。

我浏览了许多帖子/文章,并得到了一些让我走到这一步的点点滴滴,但没有什么是包罗万象的。

我也试过这个

-- Scratch variables used in the script
DECLARE @retVal INT
DECLARE @comHandle INT
DECLARE @errorSource VARCHAR(8000)
DECLARE @errorDescription VARCHAR(8000)
DECLARE @retString VARCHAR(100)

-- Initialize the COM component.
EXEC @retVal = sp_OACreate 'HTTPDLL.HTTPDLL', @comHandle OUTPUT
IF (@retVal <> 0)
BEGIN
  -- Trap errors if any
  EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, @errorDescription OUTPUT
  SELECT [Error Source] = @errorSource, [Description] = @errorDescription
  RETURN
END

(和其他此类变体)并在 sp_OAGetErrorInfo 的返回中获取此信息

“错误源描述 ODSOLE 扩展过程无效的类字符串”

也许我调用不正确,但我无法让它工作(总是返回'无效的类字符串')

预先感谢您的帮助!。

4

3 回答 3

2

您创建了一个不同于非托管扩展存储过程或 OLE 自动化 COM 对象的 CLR 程序集。在添加扩展存储过程的时候,您已经步入正轨。你不在这里这样做。您需要使用程序集中的 CREATE PROCEDURE DDL 语法创建存储过程。查看我在 SQL Server Central 上的文章的源代码和创建脚本:

http://www.sqlservercentral.com/articles/SQLCLR/65657/

您将需要对程序集的外部访问权限,它不能使用 SAFE 创建并进行这样的 Web 服务调用。除此之外,将此功能添加为触发器是一个坏主意。如果 Web 服务出现问题并且您生成未处理的 CLR 异常,则可能会导致事务失败并在触发器中回滚。除此之外,如果 Web 服务调用存在延迟,您将延迟 SQL 中事务的完成,这可能会导致阻塞和响应时间变慢。

一个更好的解决方案是使用带有外部激活器的 Service Broker 队列和通知服务来激活外部进程,以便在 SQL Server 之外异步处理队列。触发器所要做的就是向队列发送一条消息,然后就完成了。这样,如果服务调用中存在延迟或服务关闭,信息仍会被存储,并且如果您正确构建激活应用程序,它将以事务方式处理队列,因此失败会将信息保留在队列中以便稍后重试。

于 2010-02-04T15:45:16.950 回答
0

请看看这个http://dbalink.wordpress.com/2008/10/25/cannot-load-the-dll-error-in-sql-server-2005/

这可能是你需要的;-)

于 2010-02-03T22:09:26.213 回答
0

ACPerkins @ Experts-exchange 用这篇文章最糟糕的做法——触发外部事件 http://www.sqlservercentral.com/articles/Triggers/worstpracticetriggeringexternalevents/1283/启发了我们

因此,我们目前正在研究其他一些方法。谢谢你的帮助。安东尼

于 2010-02-08T19:18:33.380 回答