当数据库(SQL Server 数据库)中发生某些事件时,我们有一个业务需求能够请求 HTTP 端点。我们有一个我们控制的端点目录。我们同时使用 SQL Server 2019 和 2022。
目前我们使用Service Broker External Activator,效果很好,但这项技术已经过时,据我们所知,微软不再支持它。此外,设置/实施相当复杂,管理层将其标记为“不可行”。
当我们在 Azure 中工作时,我们将使用新的 sp_invoke_external_rest_endpoint 来调用将发出请求的 Azure 函数。这工作正常,我们将在 Azure 中使用它。
不幸的是,此过程在 SQL Server 2022 的标准本地版本中不可用。这就是我们计划使用EXECUTE sp_execute_external_script @language = N'Python'
请求 HTTP 端点的原因。
我们已经在生产中使用了 SQL Server 机器学习服务,因此我们在 SQL Server 2019 和 2022 上都提供了这些服务。我们测试了该实现,它似乎运行良好,尽管有点慢。
我们想知道:使用 Python 调用 HTTP 端点是否存在我们目前在评估中遗漏的重大缺点?
以下是我们用于概念验证的代码示例:
CREATE PROCEDURE [dbo].[usp_APICalls_HTTPRequest]
@URL NVARCHAR(100),
@Method VARCHAR(50),
@HeadersJSON NVARCHAR(MAX),
@BodyJSON NVARCHAR(MAX) = NULL,
@BodyParams NVARCHAR(MAX) = NULL,
@StatusCode VARCHAR(50) = NULL OUTPUT,
@ResponseBody NVARCHAR(MAX) = NULL OUTPUT
AS
EXECUTE sp_execute_external_script @language = N'Python',
@script = N'
import datetime
import json
import requests
print("")
print("Script started {:%Y-%m-%d %H:%M:%S}".format(datetime.datetime.now()))
print("")
objHeaders = json.loads(HeadersJSON)
if BodyJSON:
payload = json.dumps(json.loads(BodyJSON))
else:
payload = BodyParams
objReqResponse = requests.request(Method, URL, headers=objHeaders, data=payload)
objResponse = {
"StatusCode": [objReqResponse.status_code],
"Body": [objReqResponse.text]
}
StatusCode = str(objReqResponse.status_code)
ResponseBody = objReqResponse.text
print("")
print("Script complete {:%Y-%m-%d %H:%M:%S}".format(datetime.datetime.now()))
print("")
',
@params = N'@URL NVARCHAR(100),
@Method VARCHAR(50),
@HeadersJSON NVARCHAR(MAX),
@BodyJSON NVARCHAR(MAX),
@BodyParams NVARCHAR(MAX),
@StatusCode VARCHAR(50) OUTPUT,
@ResponseBody NVARCHAR(MAX) OUTPUT',
@URL = @URL,
@Method = @Method,
@HeadersJSON = @HeadersJSON,
@BodyJSON = @BodyJSON,
@BodyParams = @BodyParams,
@StatusCode = @StatusCode OUTPUT,
@ResponseBody = @ResponseBody OUTPUT
GO
与 SQL CLR 等其他扩展语言相比,使用 Python 来执行此操作没有任何缺点。
在您的事务中同步执行此操作有一个缺点。因此,您可能应该继续使用 Service Broker,并从外部激活切换到内部激活。这是数据库邮件用来发送 SMTP 请求的架构,它与 HTTP 请求有相同的问题。