Exemplo de loop: agregação de dados (DataStage®)
É possível usar o estágio Transformer para incluir informações agregadas às linhas de saída.
Operações de agregação usam um cache que armazena linhas de entrada. É possível monitorar o número de entradas no cache, configurando um nível de limite na guia Variável de loop da janela Propriedades do estágio. Se o limite for atingido quando a tarefa for executada, um aviso será emitido no log e a tarefa continuará sendo executada.
Para implementar esse cenário no estágio Transformer, faça as configurações a seguir:
- Variável de estágio
- Defina as variáveis de estágio a seguir:
- NumSavedRows
SaveInputRecord()- IsBreak
LastRowInGroup(inlink.Col1)- TotalPrice
IF IsBreak THEN SummingPrice + inlink.Price ELSE 0- SummingPrice
IF IsBreak THEN 0 ELSE SummingPrice + inlink.Price- NumRows
IF IsBreak THEN NumSavedRows ELSE 0
- Condição de loop
- Insira a expressão a seguir como a condição de loop:
O loop continua iterando para a contagem especificada na variável NumRows.@ITERATION <= NumRows - Variáveis de Loop
- Defina a variável de loopa seguir:
- SavedRowIndex
GetSavedInputRecord()
- Metadados e derivações do link de saída
- Defina as colunas do link de saída e suas derivações:
- Col1 -
inlink.Col1 - Col2 -
inlink.Col2 - Preço-
inlink.Price - Porcentagem-
(inlink.Price * 100)/TotalPrice
- Col1 -
SaveInputRecord() é chamado na primeira Variável de estágio (NumSavedRows). SaveInputRecord() salva a linha de entrada atual no cache e retorna a contagem de registros atualmente no cache. Cada linha de entrada em um grupo é salva até que o valor de quebra seja atingido. No último valor no grupo, o NumRows é configurado para o número de linhas armazenadas na cache de entrada. A Condição de loop então executa loop o número de vezes especificado por NumRows, chamando GetSavedInputRecord() a cada vez para tornar atual a próxima linha de entrada salva antes de processar novamente cada linha de entrada para criar cada linha de saída. O uso das colunas de link de entrada no link de saída refere-se a seus valores na linha de entrada recuperada atualmente, portanto, mudará em cada loop de saída.
Armazenando em cache as linhas de entrada selecionadas
É possível chamar o SaveInputRecord() dentro de uma expressão, para que as linhas de entrada sejam salvas apenas no cache quando a expressão for avaliada como true.
Por exemplo, é possível implementar o cenário descrito, mas salvar apenas linhas de entrada onde a coluna de preço não é 0. As configurações são as seguintes:
- Variável de estágio
- Defina as variáveis de estágio a seguir:
- IgnoreRow
IF (inlink.Price = 0) THEN 1 ELSE 0- NumSavedRows
IF IgnoreRecord THEN SavedRowSum ELSE SaveInputRecord()- IsBreak
LastRowInGroup(inlink.Col1)- SavedRowSum
IF IsBreak THEN 0 ELSE NumSavedRows- TotalPrice
IF IsBreak THEN SummingPrice + inlink.Price ELSE 0- SummingPrice
IF IsBreak THEN 0 ELSE SummingPrice + inlink.Price- NumRows
IF IsBreak THEN NumSavedRows ELSE 0
- Condição de loop
- Insira a expressão a seguir como a condição de loop:
@ITERATION <= NumRows - Variáveis de Loop
- Defina a variável de loopa seguir:
- SavedRowIndex
GetSavedInputRecord()
- Metadados e derivações do link de saída
- Defina as colunas do link de saída e suas derivações:
- Col1 -
inlink.Col1 - Col2 -
inlink.Col2 - Preço-
inlink.Price - Porcentagem-
(inlink.Price * 100)/TotalPrice
- Col1 -
Este exemplo produz saída similar ao exemplo anterior, mas a agregação não inclui valores de preço de 0, e nenhuma linha de saída com um valor de preço de 0 é produzida.
Produzindo linhas geradas adicionais
Este exemplo é baseado no primeiro exemplo, mas, neste caso, deseja-se identificar qualquer linha de entrada onde o Preço seja maior ou igual a 100. Se uma linha de entrada tiver um Preço maior ou igual a 100, um desconto de 25% será aplicado ao Preço e uma nova linha de saída adicional será gerada. O valor Col1 na nova linha tem 1 incluído nele para indicar uma entrada de desconto extra. A linha de entrada original ainda é produzida normalmente. Portanto, qualquer linha de entrada com um Preço maior ou igual a 100 produzirá duas linhas de saída, uma com o preço descontado e uma sem.
Os dados de entrada são mostrados na tabela a seguir:
| Col1 | Col2 | Preço |
|---|---|---|
| 1000 | abc | 100.00 |
| 1000 | def | 20.00 |
| 1000 | ghi | 60.00 |
| 1000 | jkl | 20.00 |
| 2000 | zyx | 120.00 |
| 2000 | wvu | 110.00 |
| 2000 | tsr | 170.00 |
| Col1 | Col2 | Preço | Porcentagem |
|---|---|---|---|
| 1000 | abc | 100.00 | 50.00 |
| 1001 | abc | 75.00 | 50.00 |
| 1000 | def | 20.00 | 10.00 |
| 1000 | ghi | 60.00 | 30.00 |
| 1000 | jkl | 20.00 | 10.00 |
| 2000 | zyx | 120.00 | 30.00 |
| 2001 | zyx | 90.00 | 30.00 |
| 2000 | wvu | 110.00 | 27.50 |
| 2001 | wvu | 82.50 | 27.50 |
| 2000 | tsr | 170.00 | 42.50 |
| 2001 | tsr | 127.50 | 42.50 |
Para implementar esse cenário no estágio Transformer, faça as configurações a seguir:
- Variável de estágio
- Defina as variáveis de estágio a seguir:
- NumSavedRowInt
SaveInputRecord()- AddRow
IF (inlink.Price >= 100) THEN 1 ELSE 0- NumSavedRows
IF AddRow THEN SaveInputRecord() ELSE NumSavedRowInt- IsBreak
LastRowInGroup(inlink.Col1)- TotalPrice
IF IsBreak THEN SummingPrice + inlink.Price ELSE 0- SummingPrice
IF IsBreak THEN 0 ELSE SummingPrice + inlink.Price- NumRows
IF IsBreak THEN NumSavedRows ELSE 0
- Condição de loop
- Insira a expressão a seguir como a condição de loop:
O loop continua iterando para a contagem especificada na variável NumRows.@ITERATION <= NumRows - Variáveis de Loop
- Defina as variáveis de loop a seguir:
- SavedRowIndex
GetSavedInputRecord()- AddedRow
LastAddedRow- LastAddedRow
IF (inlink.Price < 100) THEN 0 ELSE IF (AddedRow = 0) THEN 1 ELSE 0
- Metadados e derivações do link de saída
- Defina as colunas do link de saída e suas derivações:
- Col1 -
IF (inlink.Price < 100) THEN inlink.Col1 ELSE IF (AddedRow = 0) THEN inlink.Col1 ELSE inlink.Col1 + 1 - Col2 -
inlink.Col2 - Preço-
IF (inlink.Price < 100) THEN inlink.Price ELSE IF (AddedRow = 0) THEN inlink.Price ELSE inlink.Price * 0.75 - Porcentagem-
(inlink.Price * 100)/TotalPrice
- Col1 -
O SaveInputRecord é chamado uma ou duas vezes dependendo do valor de Preço. Quando SaveInputRecord é chamado duas vezes, além da agregação normal, ele produz o registro de saída extra com o valor de Preço recalculado. A Variável de loop AddedRow é usado para avaliar os valores da coluna de saída de forma diferente para cada uma das linhas de entrada duplicadas.
Erros de tempo de execução
O número de chamadas para SaveInputRecord() e GetSavedInputRecord() deve corresponder para cada loop. É possível chamar SaveInputRecord() várias vezes para incluir no cache, mas uma vez que você chamar GetSavedInputRecord(), deverá chamá-lo vezes suficientes para esvazar a cache de entrada antes de poder chamar SaveInputRecord() novamente. Os exemplos descritos poderão gerar erros de tempo de execução nas circunstâncias a seguir se esta regra não for observada:
- Se seu estágio Transformer chamar GetSavedInputRecord antes de SaveInputRecord, um erro fatal semelhante ao exemplo a seguir será relatado no log da tarefa:
APT_CombinedOperatorController,0: Fatal Error: get_record() called on record 1 but only 0 records saved by save_record() - Se seu estágio Transformer chamar GetSavedInputRecord mais vezes do que SaveInputRecord, um erro fatal semelhante ao exemplo a seguir será relatado no log da tarefa:
APT_CombinedOperatorController,0: Fatal Error: get_record() called on record 3 but only 2 records saved by save_record() - Se seu estágio Transformer chamar SaveInputRecord, mas não chamar GetSaveInputRecord, um erro fatal semelhante ao exemplo a seguir será relatado no log da tarefa:
APT_CombinedOperatorController,0: Fatal Error: save_record() called on record 3, but only 0 records retrieved by get_record() - Se seu estágio Transformer não chamar GetSavedInputRecord o número de vez que chamar SaveInputRecord, um erro fatal semelhante ao exemplo a seguir será relatado no log da tarefa:
APT_CombinedOperatorController,0: Fatal Error: save_record() called on record 3, but only 2 records retrieved by get_record()