Курсор U-SQL в Azure Data Lake

Мне нужно обработать данные в Azure Data Lake. Мой поток выглядит следующим образом:

  1. Я хотел бы выбрать из списка идентификаторов базы данных для следующей обработки. Это я сделал.
  2. Мне нужно перебирать идентификаторы (с первого шага), и мне нужно последовательно экспортировать данные в отдельные файлы (разделенные по идентификатору)

Проблема связана с statemanet:

Процедуры U-SQL не предоставляют никаких императивных конструкций потока кода, таких как циклы for или while.

Любая идея, как обрабатывать данные так же, как с курсором?

Я не нашел никакой документации по курсорам в U-SQL.

Благодарю вас!


person peterko    schedule 06.03.2017    source источник
comment
Это то же самое, что и ваш другой вопрос. Повторяю, USQL не для повторения.   -  person Paul Andrew    schedule 07.03.2017
comment
Это не то же самое, этот вопрос связан с курсором или циклами и подобными случаями (другой мой вопрос связан с разбиением файла). Это было причиной, по которой я разделил вопросы, потому что я хотел бы знать, возможен ли итеративный подход или нет, и в моем другом вопросе я хотел бы знать, как разделить файл по значению ключа.   -  person peterko    schedule 07.03.2017


Ответы (2)


В U-SQL нет курсоров из-за оператора, на который вы ссылаетесь выше.

U-SQL не предоставляет никаких императивных конструкций потока кода, поскольку это препятствует возможности оптимизатора глобально оптимизировать ваш скрипт.

Вы должны думать о подходе к своей проблеме декларативно. Например, если у вас есть список идентификаторов (либо в таблице, либо в SqlArray, либо даже в файле), используйте декларативное соединение. Например, вы хотите добавить 42 к каждому значению, где ключ находится в списке существующих ключей:

// Two options for providing the "looping data"
// Option 1: Array Variable
DECLARE @keys_var = new SqlArray<string>{"k1", "k2", "k3"};

// Option 2: Rowset (eg from an EXTRACT from file, a table or other place)
@keys = SELECT * FROM (VALUES("k1"), ("k2"), ("k3")) AS T(key);

// This is the data you want to iterate over to add 42 to the value column for every matching key
@inputdata = SELECT * FROM (VALUES (1, "k1"), (2, "k1"), (3, "k2"), (6, "k5")) AS T(value, key);

//Option 1:
@res = SELECT value+42 AS newval, key FROM @inputdata WHERE @keys_var.Contains(key);

OUTPUT @res TO "/output/opt1.csv" USING Outputters.Csv();

//Option 2:
@res = SELECT value+42 AS newval, i.key 
    FROM @inputdata AS i INNER JOIN @keys AS k 
         ON i.key == k.key;

OUTPUT @res TO "/output/opt2.csv" USING Outputters.Csv();

Теперь в вашем случае вы хотите иметь наборы выходных файлов, управляемые данными. В настоящее время над этой функцией ведется работа (это одно из наших популярные запросы). До тех пор вам нужно будет написать сценарий для создания сценария (я приведу пример по вашему другому вопросу).

person Michael Rys    schedule 08.03.2017
comment
Спасибо, Майкл. Не могли бы вы описать, что вы имели в виду под декларативным соединением? У вас есть пример или учебник? - person peterko; 08.03.2017
comment
Обновлено выше. Обратите внимание, что это работает не для OUTPUT, а для общей обработки. - person Michael Rys; 08.03.2017

Если вам действительно нужно итеративное поведение, вам нужно вызвать USQL из PowerShell.

Например:

ForEach ($Date in $Dates)
    {
    $USQLProcCall = '[dbo].[usp_OutputDailyAvgSpeed]("' + $Date + '");'
    $JobName = 'Output daily avg dataset for ' + $Date

    Write-Host $USQLProcCall

    $job = Submit-AzureRmDataLakeAnalyticsJob `
        -Name $JobName `
        -AccountName $DLAnalyticsName `
        –Script $USQLProcCall `
        -DegreeOfParallelism $DLAnalyticsDoP

    Write-Host "Job submitted for " $Date
    }

Источник: https://www.purplefrogsystems.com/paul/2017/05/recursive-u-sql-with-powershell-u-sql-looping/

person Paul Andrew    schedule 07.05.2017
comment
Спасибо, Пол. Я частично решил это с помощью циклов в рабочем процессе Powershell с использованием u-sql. Теперь попробую ваши предложения. Большое спасибо! - person peterko; 07.05.2017