# Macros

> Macros SQL do MacroTranslator Sankhya (`dbDate`, `nullValue`, `ignorecase`, `normalizeText`, `truncMonth`, `yearMonth`, `addMonths`) para portabilidade Oracle/MSSQL. Use ao escrever, revisar, auditar ou portar SQL em `queries/`, `datadictionary/`, dbscripts ou `@NativeQuery`, ao identificar oportunidades de substituir SQL específico de banco por macro, ou ao diagnosticar diferenças de comportamen…

- **Type:** Skill
- **Install:** `agentstack add skill-snk-devcenter-addon-studio-macros`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [snk-devcenter](https://agentstack.voostack.com/s/snk-devcenter)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [snk-devcenter](https://github.com/snk-devcenter)
- **Source:** https://github.com/snk-devcenter/addon-studio/tree/main/plugins/addon-studio/skills/macros

## Install

```sh
agentstack add skill-snk-devcenter-addon-studio-macros
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Macros SQL Sankhya (MacroTranslator) — Addon Studio 2.0

Macros SQL traduzidas automaticamente entre Oracle e MSSQL pelo framework Sankhya. Permite escrever queries portáveis sem duplicar sintaxe por banco.

> **Onde aparecem:**
> - `` em metadata XML (`datadictionary/`) — quando contem SQL
> - `selectQuery` em `` (lookup customizado)
> - `@Criteria(clause = "...")` em `@Repository`
> - `@NativeQuery("...")` em `@Repository`
> - Queries externas em `model/src/main/resources/queries/*.sql` ou `queries/*.xml`
>
> **Nao confundir com BeanShell**: variaveis `$col_`, `$ctx_usuario_logado`, `$ctx_dh_atual` sao contexto **BeanShell** em `` — nao sao macros SQL. Ver `data-dictionary` §1.8.

---

## 1. Por que usar macros

- **Sintaxe unificada** Oracle/MSSQL — escrita uma vez, traduzida automaticamente
- **Centraliza diferencas** de banco em um unico ponto
- **Reduz risco** de query funcionar em um banco e quebrar no outro
- **Manutencao** em um lugar so (sem ramificacoes por banco)

---

## 2. Referencia por categoria

### 2.1 Data e hora

| Macro                          | Proposito                                          | Exemplo                          |
|:-------------------------------|:---------------------------------------------------|:---------------------------------|
| `dbDate()`                     | Data/hora atual do banco (`SYSDATE`/`GETDATE()`)   | `WHERE DTMOV = dbDate()`         |
| `onlydate()`             | Apenas a data (sem hora)                           | `onlydate(DATA_VENDA)`           |
| `truncDate()`            | Apenas a data (similar a `onlydate`)               | `truncDate(DATA)`                |
| `truncWeek()`            | Inicio da semana                                   | `truncWeek(DATA)`                |
| `truncMonth()`           | Inicio do mes                                      | `truncMonth(DATA)`               |
| `truncQarter()`          | Inicio do trimestre (nome com typo no SDK: `Qarter`)| `truncQarter(DATA)`             |
| `truncYear()`            | Inicio do ano                                      | `truncYear(DATA)`                |
| `getDay()`               | Dia (1-31)                                         | `getDay(DATA)`                   |
| `getMonth()`             | Mes (1-12)                                         | `getMonth(DATA)`                 |
| `getYear()`              | Ano (`YYYY`)                                       | `getYear(DATA)`                  |
| `monYear()`              | Mes/ano formato `MM/YYYY`                          | `monYear(DATA)`                  |
| `yearMonth()`            | Ano+mes formato `YYYYMM` (numerico)                | `yearMonth(DATA)`                |
| `addMonths(, )`     | Soma N meses a data                                | `addMonths(DATA, 3)`             |
| `endOfCurrentMonth()`          | Ultimo dia do mes atual                            | `endOfCurrentMonth()`            |
| `diffdays(, )`       | Diferenca em dias (`dt1 - dt2`)                    | `diffdays(DTFIM, DTINI)`         |
| `diffhour(, )`       | Diferenca em horas (`dt1 - dt2`)                   | `diffhour(DTFIM, DTINI)`         |
| `convertPtBrDate()`      | Data como string `DD/MM/YYYY`                      | `convertPtBrDate(DATA)`          |

### 2.2 Texto

| Macro                                | Proposito                                       | Exemplo                                   |
|:-------------------------------------|:------------------------------------------------|:------------------------------------------|
| `ignorecase()`                 | Compara sem case e sem acentos                  | `ignorecase(NOME) = ignorecase('Jose')`   |
| `normalizeText()`              | Remove acentos + UPPER (busca tolerante)        | `normalizeText(NOME) LIKE '%SILVA%'`      |
| `upperText()`                  | Converte para maiusculas                        | `upperText(NOME)`                         |
| `trim()`                       | Remove espacos nas pontas                       | `trim(NOME)`                              |
| `length()`                     | Tamanho da string                               | `length(NOME)`                            |
| `subString(, , )`     | Recorte de string                               | `subString(NOME, 1, 5)`                   |
| `stringIndex(, )`          | Posicao de substring (1-based)                  | `stringIndex(NOME, 'A')`                  |
| `leftPad(, , )`      | Preenche a esquerda ate atingir tamanho         | `leftPad(CODIGO, '0', 8)`                 |
| `concatstr(, )`                | Concatena duas strings (`||` Oracle / `+` MSSQL)| `concatstr(NOME, SOBRENOME)`              |
| `quebraLinha()`                      | Quebra de linha (`CRLF`)                        | `concatstr(NOME, quebraLinha())`          |

### 2.3 Conversao de tipos

| Macro                            | Proposito                              | Exemplo                       |
|:---------------------------------|:---------------------------------------|:------------------------------|
| `convertToNumber()`        | Converte para `NUMERIC`/`NUMBER`       | `convertToNumber(PRECO)`      |
| `convertToFloat()`         | Converte para `FLOAT`                  | `convertToFloat(VALOR)`       |
| `convertToVarchar()`       | Converte para `VARCHAR`                | `convertToVarchar(CODIGO)`    |
| `convertToTimestamp()`     | Converte para `TIMESTAMP`/`DATETIME`   | `convertToTimestamp(STR_DATA)`|
| `convertToMilliseconds()`  | Extrai milissegundos                   | `convertToMilliseconds(DATA)` |

### 2.4 Outros

| Macro                              | Proposito                                            | Exemplo                              |
|:-----------------------------------|:-----------------------------------------------------|:-------------------------------------|
| `nullValue(, )`      | `NVL`/`ISNULL`: substitui null por padrao            | `nullValue(SALARIO, 0)`              |
| `maxLines()`                  | Limita linhas (`ROWNUM` Oracle / `TOP` MSSQL)        | `SELECT maxLines(10) * FROM TGFCAB`  |
| `${user.name}`                     | Owner/usuario do banco (prefixo de tabela)           | `SELECT * FROM ${user.name}TABELA`   |
| `sqldatabase.`             | Qualifica tabela com nome do banco/schema            | `SELECT * FROM sqldatabase.CLIENTES` |

---

## 3. Uso em `` SQL (datadictionary)

Algumas `` em metadata podem conter **SQL** (nao BeanShell). Macros SQL valem aqui:

```xml

    Data Referencia
    

    Vlr Total (Tratado)
    

```

> Para `` **BeanShell** (mais comum em campos com `$col_*`/`$ctx_*`), use as variaveis de contexto BeanShell — **nao** macros SQL. Ver `data-dictionary` §1.8.

---

## 4. Uso em `@Criteria` / `@NativeQuery`

```java
// Busca tolerante a acento e case
@Criteria(clause = "ignorecase(this.NOMEPARC) = ignorecase(:nome)")
List findByNome(String nome);

// Filtro por data atual do servidor
@Criteria(clause = "this.DTMOV = dbDate()")
List findHoje();

// Agrupamento por competencia (ano+mes)
@NativeQuery("SELECT yearMonth(DTNEG) AS COMP, SUM(VLRNOTA) AS TOTAL " +
             "FROM TGFCAB GROUP BY yearMonth(DTNEG)")
List agruparPorCompetencia();

// Tratamento de null
@NativeQuery("SELECT nullValue(VLRDESCONTO, 0) FROM TGFCAB WHERE NUNOTA = :nu")
BigDecimal descontoOrZero(BigDecimal nu);

// Limite de linhas portatil
@NativeQuery("SELECT maxLines(10) NUNOTA, VLRNOTA FROM TGFCAB ORDER BY DTNEG DESC")
List ultimas10();
```

---

## 5. Uso em queries externas (`queries/*.sql`)

Macros tambem funcionam em arquivos externos referenciados via `fromFile = true`:

```sql
-- queries/ranking-vendedores.sql
SELECT VEND.CODVEND, VEND.NOMEVEND,
       SUM(nullValue(CAB.VLRNOTA, 0)) AS TOTAL,
       getYear(CAB.DTNEG) AS ANO
FROM TGFCAB CAB
INNER JOIN TGFVEN VEND ON VEND.CODVEND = CAB.CODVEND
WHERE truncMonth(CAB.DTNEG) = truncMonth(dbDate())
  AND ignorecase(VEND.NOMEVEND) LIKE ignorecase(:nome)
GROUP BY VEND.CODVEND, VEND.NOMEVEND, getYear(CAB.DTNEG)
```

---

## 6. Anti-Patterns (PROIBIDO)

| Anti-Pattern                                              | Correcao                                            |
|:----------------------------------------------------------|:----------------------------------------------------|
| Usar `SYSDATE`/`GETDATE()` direto                         | `dbDate()`                                          |
| Usar `NVL`/`ISNULL` direto                                | `nullValue(, )`                       |
| Usar `ROWNUM`/`TOP` direto                                | `maxLines()`                                   |
| Concatenacao com `||` ou `+`                              | `concatstr(, )`                               |
| `UPPER(...)` sem tratar acentos em busca textual          | `normalizeText()` ou `ignorecase()`     |
| `INSTR`/`CHARINDEX` direto                                | `stringIndex(, )`                         |
| `TO_NUMBER`/`CONVERT(NUMERIC, ...)` direto                | `convertToNumber()`                           |
| `TO_CHAR(...)`/`CONVERT(VARCHAR, ...)` direto             | `convertToVarchar()` ou `convertPtBrDate(...)`|
| `LPAD`/`RIGHT(REPLICATE(...))` direto                     | `leftPad(, , )`                     |
| `SUBSTR`/`SUBSTRING` direto                               | `subString(, , )`                    |
| `ADD_MONTHS`/`DATEADD(MONTH, ...)` direto                 | `addMonths(, )`                          |
| `LAST_DAY(SYSDATE)`/`EOMONTH(GETDATE())`                  | `endOfCurrentMonth()`                               |

---

## 7. Quando NAO usar macro

- **Operacao muito especifica** de um banco sem equivalente no outro (ex.: window function avancada Oracle-only). Nesses casos, separar em `queries/.xml` com tags `` e ``. Ver `repository` §4.
- **Logica em `` BeanShell** (nao SQL). Use variaveis de contexto BeanShell (`$col_*`, `$ctx_*`).
- **DDL** em `dbscripts/` — scripts de banco ja sao split via tags ``/``. Macros nao se aplicam ali.

## Skills relacionadas

- `data-dictionary` — macros usadas em campo `` quando contém SQL (não BeanShell)
- `repository` — macros usadas em `@NativeQuery` e `queries/.xml`
- `database` — dbscripts **não** usam macros (ver seção 7); portabilidade ali é via split ``/``

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [snk-devcenter](https://github.com/snk-devcenter)
- **Source:** [snk-devcenter/addon-studio](https://github.com/snk-devcenter/addon-studio)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-snk-devcenter-addon-studio-macros
- Seller: https://agentstack.voostack.com/s/snk-devcenter
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
