SQL Server 2016: R Services, часть 3, примеры запуска команд на R

Мы подошли, пожалуй, к самому интересному, запуску команд на R внутри SQL Server. Это можно сделать с помощью отдельной хранимой процедуры sp_execute_external_script, у которой есть несколько параметров.

В первую очередь это обязательные параметры @language и @script. Первый пока может принимать только одно значение – R. В будущем планируется добавить поддержку других языков. А во второй вы передаете код на языке R, который хотите выполнить. Ниже я привожу пример самого простого скрипта, который вам вернет информацию по встроенному набору данных iris, а также результат его выполнения.

execute sp_execute_external_script
	@language = N'R',
	@script = N'str(iris);'
with result sets none;
go

Все остальные параметры опциональны, однако, скорее всего, вы ими постоянно будет пользоваться. Например, параметр @input_data_1 принимает запрос на языке T-SQL, возвращающий набор данных, который может быть использован внутри скрипта на R. В R скрипте вы сможете обращаться к этому набору данных по имени InputDataSet, если вы не задали другое значение в параметре @input_data_1_name. На текущий момент поддерживается только один входящий набор данных. Если в результате работы вашего скрипта вы хотите сформировать набор данных и вернуть его назад в SQL Server, то в скрипте вы должны сформировать data frame с именем OutputDataSet, либо любым другим именем, которое вы должны передать в параметре @output_data_1_name. Ниже вы можете увидеть пример скрипта, в который я передаю запрос, возвращающий всего лишь одно значение 1, а R скрипт просто возвращает входящий набор как есть, без изменений.

execute sp_execute_external_script
	@language = N'R',
	@script = N'OutputDataSet <- InputDataSet;',
	@input_data_1 = N'select 1;'
with result sets undefined;
go

Также я могу задать свои имена для входящего и исходящего наборов данных, если мне по каким-то причинам не хочется или неудобно использовать значения по умолчанию.

execute sp_execute_external_script
	@language = N'R',
	@script = N'SQLOut <- SQLIn;',
	@input_data_1 = N'select 1;',
	@input_data_1_name = N'SQLIn',
	@output_data_1_name = N'SQLOut'
with result sets undefined;
go

Результат работы будет тот же самый. И если вы внимательно посмотрите, то у вазвращаемого набора данных нет даже названия колонки. Это происходит из-за того, что я указал опцию with results set undefined. Если же я хочу возвращать строго типизированный набор, то я должен его описать, например вот так:

execute sp_execute_external_script
	@language = N'R',
	@script = N'SQLOut <- SQLIn;',
	@input_data_1 = N'select 1 as id, N''qwe'' as name, cast(''20000101'' as datetime) as dt;',
	@input_data_1_name = N'SQLIn',
	@output_data_1_name = N'SQLOut'
with result sets undefined;
go
 
execute sp_execute_external_script
	@language = N'R',
	@script = N'SQLOut <- SQLIn;',
	@input_data_1 = N'select 1 as id, N''qwe'' as name, cast(''20000101'' as datetime) as dt;',
	@input_data_1_name = N'SQLIn',
	@output_data_1_name = N'SQLOut'
with result sets ((id int not null, name varchar(100) not null, dt datetime not null));
go

Кроме передачи данных как набора, можно также передать и вернуть значения в виде переменных. Для этого существует отдельный параметр @params, в котором вы должны объявить все переменные, которые будут использоваться. После этого вы все их также передаете в хранимую процедуру, а для возвращаемых параметров указываете ключевое слово output.

declare @in_v int = 100, @out_v int;
 
execute sp_execute_external_script
	@language = N'R',
	@script = N'out_v1 <- in_v1;',
	@params = N'@in_v1 int, @out_v1 int output',
	@in_v1 = @in_v,
	@out_v1 = @out_v output
with result sets none;
 
select @out_v;
go

На этом базовое введение в запуск команд на R внутри SQL Server можно считать оконченным. В следующих частях я подробно расскажу о тонкостях поведения R Services при передаче и возвращении данных, поддержке различных типов данных, а также мы начнем рассматривать более сложные примеры, параллельное выполнение кода и обработку больших объемов данных.