sp_execute_external_script (Transact-SQL)

适用于: SQL Server 2016 (13.x) 及更高版本 Azure SQL 托管实例

存储过程sp_execute_external_script执行作为过程的输入参数提供的脚本,并用于机器学习服务和语言扩展

对于 机器学习 服务,支持 PythonR 语言。 对于语言扩展,支持 Java,但必须使用 CREATE EXTERNAL LANGUAGE 定义

若要执行sp_execute_external_script,必须先安装机器学习服务或语言扩展。 有关详细信息,请参阅在 WindowsLinux 上安装 SQL Server 机器学习 Services (Python 和 R),或在 WindowsLinux 上安装 SQL Server 语言扩展。

sp_execute_external_script存储过程执行作为该过程的输入参数提供的脚本,并与 SQL Server 2017 上的 机器学习 Services (14.x) 一起使用

对于 机器学习 服务,支持 PythonR 语言。

若要执行sp_execute_external_script,必须先安装机器学习服务。 有关详细信息,请参阅在 Windows 上安装 SQL Server 机器学习 Services (Python 和 R)。

sp_execute_external_script存储过程执行作为过程的输入参数提供的脚本,并与 SQL Server 2016 (13.x)上的 R Services 一起使用

对于 R 服务, R 是受支持的语言。

若要执行 sp_execute_external_script,必须先安装 R Services。 有关详细信息,请参阅在 Windows 上安装 SQL Server 机器学习 Services (Python 和 R)。

sp_execute_external_script存储过程执行作为过程的输入参数提供的脚本,并将其与 Azure SQL 托管实例 中的 机器学习 Services 一起使用

对于 机器学习 服务,支持 PythonR 语言。

若要执行sp_execute_external_script,必须先启用机器学习服务。 有关详细信息,请参阅 Azure SQL 托管实例 文档中的 机器学习 服务。

Transact-SQL 语法约定

语法

sp_execute_external_script
    [ @language = ] N'language'
    , [ @script = ] N'script'
    [ , [ @input_data_1 = ] N'input_data_1' ]
    [ , [ @input_data_1_name = ] N'input_data_1_name' ]
    [ , [ @input_data_1_order_by_columns = ] N'input_data_1_order_by_columns' ]
    [ , [ @input_data_1_partition_by_columns = ] N'input_data_1_partition_by_columns' ]
    [ , [ @output_data_1_name = ] N'output_data_1_name' ]
    [ , [ @parallel = ] { 0 | 1 } ]
    [ , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ] [ , ...n ]' ]
    [ , [ @parameter1 = ] 'value1' [ OUT | OUTPUT ] [ , ...n ] ]
[ ; ]

SQL Server 2017 和早期版本的语法

EXEC sp_execute_external_script
    @language = N'language'
    , @script = N'script'
    [ , [ @input_data_1 = ] N'input_data_1' ]
    [ , [ @input_data_1_name = ] N'input_data_1_name' ]
    [ , [ @output_data_1_name = ] N'output_data_1_name' ]
    [ , [ @parallel = ] { 0 | 1 } ]
    [ , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ] [ ,...n ]' ]
    [ , [ @parameter1 = ] 'value1' [ OUT | OUTPUT ] [ ,...n ] ]

参数

[ @language = ] N'language'

指示脚本语言。 语言sysname。 有效值为 RPython 和使用 CREATE EXTERNAL LANGUAGE 定义的任何语言(例如 Java)。

指示脚本语言。 语言sysname。 在 SQL Server 2017(14.x)中,有效值为 RPython

指示脚本语言。 语言sysname。 在 SQL Server 2016(13.x)中,唯一的有效值为 R

指示脚本语言。 语言sysname。 在Azure SQL 托管实例中,有效值为 RPython

[ @script = ] N'script'

指定为文本或变量输入的外部语言脚本。 脚本nvarchar(max)。

[ @input_data_1 = ] N'input_data_1'

以 Transact-SQL 查询的形式指定外部脚本使用的输入数据。 input_data_1数据类型为 nvarchar(max)。

[ @input_data_1_name = ] N'input_data_1_name'

指定用于表示由 @input_data_1 定义的查询的变量的名称。 外部脚本中变量的数据类型取决于语言。 对于 R,输入变量是数据帧。 对于 Python,输入必须是表格格式。 input_data_1_name为 sysname。 默认值为 InputDataSet

[ @input_data_1_order_by_columns = ] N'input_data_1_order_by_columns'

用于生成每分区模型。 指定用于对结果集进行排序的列的名称,例如产品名称。 外部脚本中变量的数据类型取决于语言。 对于 R,输入变量是数据帧。 对于 Python,输入必须是表格格式。

[ @input_data_1_partition_by_columns = ] N'input_data_1_partition_by_columns'

用于生成每分区模型。 指定用于对数据进行分段的列的名称,例如地理区域或日期。 外部脚本中变量的数据类型取决于语言。 对于 R,输入变量是数据帧。 对于 Python,输入必须是表格格式。

[ @output_data_1_name = ] N'output_data_1_name'

指定外部脚本中变量的名称,其中包含在存储过程调用完成后要返回到 SQL Server 的数据。 外部脚本中变量的数据类型取决于语言。 对于 R,输出必须是数据帧。 对于 Python,输出必须是 pandas 数据帧。 output_data_1_namesysname。 默认值为 OutputDataSet

[ @parallel = ] { 0 | 1 }

通过将参数设置为 @parallel1 启用 R 脚本的并行执行。 此参数的默认值为 0 (无并行度)。 如果 @parallel = 1 直接将输出流式传输到客户端计算机,则需要子 WITH RESULT SETS 句,并且必须指定输出架构。

  • 对于不使用 RevoScaleR 函数的 R 脚本,使用 @parallel 参数对处理大型数据集很有用,假设脚本可以简单并行化。 例如,将 R predict 函数与模型一起使用以生成新预测时,将其设置为 @parallel = 1 查询引擎的提示。 如果查询可以并行化,则根据 MAXDOP 设置分布行。

  • 对于使用 RevoScaleR 函数的 R 脚本,并行处理会自动处理,不应指定 @parallel = 1 调用 sp_execute_external_script

[ @params = ] N'@parameter_name data_type' [ OUT |OUTPUT ] [ ,...n ]

外部脚本中使用的输入参数声明的列表。

[ @parameter1 = ] 'value1' [ OUT |OUTPUT ] [ ,...n ]

外部脚本使用的输入参数的值列表。

注解

重要

查询树由 SQL 机器学习控制,用户无法对查询执行任意操作。

用于 sp_execute_external_script 执行以支持的语言编写的脚本。 支持的语言是 PythonR 与 机器学习 Services 一起使用,以及使用 CREATE EXTERNAL LANGUAGE(例如 Java)定义的与语言扩展一起使用的任何语言。

用于 sp_execute_external_script 执行以支持的语言编写的脚本。 支持的语言是 SQL Server 2017 (14.x) 机器学习服务中的 PythonR

用于 sp_execute_external_script 执行以支持的语言编写的脚本。 唯一支持的语言是 SQL Server 2016 (13.x) R 服务中的 R

用于 sp_execute_external_script 执行以支持的语言编写的脚本。 支持的语言是 Azure SQL 托管实例 机器学习 Services 中的 PythonR

默认情况下,此存储过程返回的结果集是带有未命名列的输出。 脚本中使用的列名是脚本环境的本地名称,不会反映在输出的结果集中。 若要命名结果集列,请使用 WITH RESULT SET . 的 EXECUTE子句。

除了返回结果集外,还可以使用 OUTPUT 参数返回标量值。

可以通过配置外部资源池来控制外部脚本使用的资源。 有关详细信息,请参阅 CREATE EXTERNAL RESOURCE POOL (Transact-SQL)。 可以从资源调控器目录视图、DMV 和计数器获取有关工作负荷的信息。 有关详细信息,请参阅 资源调控器目录视图(Transact-SQL)资源调控器相关的动态管理视图(Transact-SQL)SQL Server 外部脚本对象

监视脚本执行

使用 sys.dm_external_script_requestssys.dm_external_script_execution_stats监视脚本执行。

分区建模的参数

可以设置两个附加参数,用于对分区数据进行建模,其中分区基于一个或多个列,这些列自然地将数据集分段为逻辑分区,仅在脚本执行期间创建和使用。 包含年龄、性别、地理区域、日期或时间重复值的列是一些适合分区数据集的示例。

这两个参数是 input_data_1_partition_by_columnsinput_data_1_order_by_columns,其中第二个参数用于对结果集进行排序。 参数作为输入 sp_execute_external_script 传递给每个分区执行一次的外部脚本。 有关详细信息和示例,请参阅 教程:创建基于分区的模型

可以通过指定 @parallel = 1来并行执行脚本。 如果可以并行化输入查询,则应将其设置为 @parallel = 1 参数 sp_execute_external_script的一部分。 默认情况下,查询优化器在表上运行 @parallel = 1 的行数超过 256 行,但如果要显式处理,此脚本将参数作为演示包含。

提示

对于训练工作负载,可以将 @parallel 用于任意训练脚本,甚至是那些使用非 Microsoft-rx 算法的脚本。 通常,只有 RevoScaleR 算法(带有 rx 前缀)支持在 SQL Server 的训练方案中并行执行。 但是,使用 SQL Server 2019(15.x)及更高版本中的新参数,可以并行化调用未专门设计的功能的脚本。

Python 和 R 脚本的流式执行

流式处理允许 Python 或 R 脚本处理的数据超出内存中可以容纳的数据。 若要控制流式处理期间传递的行数,请在集合中@params指定参数@r_rowsPerRead的整数值。 例如,如果要训练使用非常宽数据的模型,则可以调整值以读取较少的行,以确保所有行都可以在一个数据区块中发送。 还可以使用此参数来管理一次读取和处理的行数,以缓解服务器性能问题。

@r_rowsPerRead流式处理参数和@parallel参数都应被视为提示。 若要应用提示,必须能够生成包含并行处理的 SQL 查询计划。 如果无法执行此操作,则无法启用并行处理。

注意

流式处理和并行处理仅在企业版受支持。 可以在标准版中包含参数,而不会引发错误,但参数不起作用,R 脚本在单个进程中运行。

限制

数据类型

在过程的输入查询或参数 sp_execute_external_script 中使用时,不支持以下数据类型,并返回不受支持的类型错误。

解决方法 CAST 是在将列或值发送到外部脚本之前,在 Transact-SQL 中支持的类型。

  • cursor
  • timestamp
  • datetime2datetimeoffsettime
  • sql_variant
  • 文本图像
  • xml
  • hierarchyidgeometrygeography
  • CLR 用户定义的类型

通常,无法映射到 Transact-SQL 数据类型的任何结果集都将输出为 NULL

特定于 R 的限制

如果输入包含 与 R 中允许的值范围不匹配的日期/时间 值,则值将 NA转换为 。 这是必需的,因为 SQL 机器学习允许的值范围大于 R 语言支持的范围。

尽管这两种语言都使用 I企业版E 754,但 SQL 机器学习不支持浮点值(例如,+Inf-InfNaN例如,)不支持。 当前行为只是将值直接发送到 SQL;因此,SQL 客户端会引发错误。 因此,这些值将转换为 NULL

权限

需要 EXECUTE ANY EXTERNAL SCRIPT 数据库权限。

示例

本部分包含有关如何使用 Transact-SQL 执行 R 或 Python 脚本的存储过程的示例。

A. 将 R 数据集返回到 SQL Server

以下示例创建一个存储过程,用于 sp_execute_external_script 返回 R 附带的鸢尾花数据集。

DROP PROCEDURE IF EXISTS get_iris_dataset;
GO
CREATE PROCEDURE get_iris_dataset
AS
BEGIN
    EXEC sp_execute_external_script @language = N'R',
        @script = N'iris_data <- iris;',
        @input_data_1 = N'',
        @output_data_1_name = N'iris_data'
    WITH RESULT SETS((
        "Sepal.Length" FLOAT NOT NULL,
        "Sepal.Width" FLOAT NOT NULL,
        "Petal.Length" FLOAT NOT NULL,
        "Petal.Width" FLOAT NOT NULL,
        "Species" VARCHAR(100)
    ));
END;
GO

B. 创建 Python 模型并通过该模型生成分数

此示例演示如何在 sp_execute_external_script 简单的 Python 模型上生成分数。

CREATE PROCEDURE [dbo].[py_generate_customer_scores]
AS
BEGIN
    -- Input query to generate the customer data
    DECLARE @input_query NVARCHAR(MAX) = N'SELECT customer, orders, items, cost FROM dbo.Sales.Orders'

    EXEC sp_execute_external_script @language = N'Python',
        @script = N'
import pandas as pd
from sklearn.cluster import KMeans

# Get data from input query
customer_data = my_input_data

# Define the model
n_clusters = 4
est = KMeans(n_clusters=n_clusters, random_state=111).fit(customer_data[["orders","items","cost"]])
clusters = est.labels_
customer_data["cluster"] = clusters

OutputDataSet = customer_data
',
        @input_data_1 = @input_query,
        @input_data_1_name = N'my_input_data'
    WITH RESULT SETS((
        "CustomerID" INT,
        "Orders" FLOAT,
        "Items" FLOAT,
        "Cost" FLOAT,
        "ClusterResult" FLOAT
    ));
END;
GO

Python 代码中使用的列标题不会输出到 SQL Server;因此,使用 WITH RESULT 语句指定 SQL 要使用的列名和数据类型。

°C 基于 SQL Server 中的数据生成 R 模型

以下示例创建一个存储过程,用于 sp_execute_external_script 生成鸢尾花模型并返回模型。

注意

此示例需要提前安装 e1071 包。 有关详细信息,请参阅 在 SQL Server 上安装其他 R 包。

DROP PROCEDURE IF EXISTS generate_iris_model;
GO
CREATE PROCEDURE generate_iris_model
AS
BEGIN
    EXEC sp_execute_external_script @language = N'R',
        @script = N'
      library(e1071);
      irismodel <-naiveBayes(iris_data[,1:4], iris_data[,5]);
      trained_model <- data.frame(payload = as.raw(serialize(irismodel, connection=NULL)));
',
        @input_data_1 = N'select "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species" from iris_data',
        @input_data_1_name = N'iris_data',
        @output_data_1_name = N'trained_model'
    WITH RESULT SETS((model VARBINARY(MAX)));
END;
GO

要生成使用 Python 的类似模型,需要将语言标识符从 @language=N'R' 更改为 @language = N'Python',并对 @script 参数进行必要的修改。 否则,所有参数均与 R 在功能上相同。

要进行评分,还可以使用本机 PREDICT 函数,此函数无需调用 Python 或 R 运行时,因此更加快速。