Bancos de dados
Os quatro bancos SQL suportados seguem o mesmo desenho: a Coleta roda uma consulta em intervalo agendado e transforma o resultado em mensagens; a Entrega roda um comando de escrita (ou procedure) com os dados da mensagem. Esta página descreve o que vale para todos eles.
O que muda de um para outro — os campos da conexão, o que o motor oferece e as particularidades do dialeto — está na página de cada um:
| Banco | Coleta | Entrega |
|---|---|---|
| SQL Server | SQL_SERVER | SQL_SERVER_EXEC |
| Oracle | ORACLE | ORACLE_EXEC |
| PostgreSQL (inclui TimescaleDB) | POSTGRES | POSTGRES_EXEC |
| SQLite | SQLITE | SQLITE_EXEC |
| InfluxDB | INFLUXDB | INFLUXDB_WRITE |
| MongoDB | MONGODB | MONGODB_WRITE |
Em todos eles, a conexão é cadastrada em Conexões Externas. Senhas são gravadas criptografadas e nunca voltam para a tela — ao editar, o campo em branco mantém a senha atual.
O InfluxDB também aparece na lista acima, mas não segue este desenho: não tem Coluna Chave nem Comando Pós-Coleta (a varredura incremental se faz pela janela de tempo da consulta) e a Entrega grava line protocol em vez de executar um comando. Veja a página dele.
O MongoDB também tem desenho próprio: a consulta é um filtro ou um pipeline em JSON (não SQL) e a Entrega grava o documento direto, sem comando. Veja a página dele.
Coleta — SQL_SERVER / ORACLE / POSTGRES / SQLITE
O CMS executa a Query SELECT no intervalo agendado da Coleta e transforma o resultado em mensagens. O Modo do Resultado decide a granularidade:
| Modo | Resultado |
|---|---|
LINHA_UNICA_PAYLOAD_UNICO | Todo o resultado vira uma mensagem (array JSON com todas as linhas) |
UMA_LINHA_POR_PAYLOAD | Cada linha vira uma mensagem independente (objeto JSON) |
Cada execução abre a conexão, consulta e fecha — não há pool mantido entre ciclos. O Timeout da
Coleta limita o tempo de conexão no SQL Server, no Oracle e no PostgreSQL (onde vale também como
statement_timeout da sessão); no SQLite ele não tem efeito, porque lá o que faz uma execução
esperar é o lock do arquivo.
Marcar o que já foi lido
Para não coletar os mesmos registros na execução seguinte, configure o par Coluna Chave + Comando Pós-Coleta:
- Coluna Chave — nome da coluna retornada pela Query SELECT que identifica cada linha (ex.:
id). - Comando Pós-Coleta — comando de escrita rodado logo após a consulta, com o placeholder
:idssubstituído pela lista de valores daquela coluna nas linhas recém-coletadas.
-- Query SELECT
SELECT id, ordem, quantidade FROM fila_producao WHERE processado = 0
-- Comando Pós-Coleta
UPDATE fila_producao SET processado = 1 WHERE id IN (:ids)O :ids é uma lista de tamanho variável, então vai concatenado no comando (valores de texto são
escapados); os demais valores continuam indo como bind. O comando pós-coleta só roda se a consulta
trouxe linhas e se a Coluna Chave trouxe valor.
Sem esse par — ou sem uma consulta que filtre o que já foi lido — a próxima execução coleta os mesmos registros de novo. O CMS não mantém cursor de leitura por você.
Parâmetros na consulta
Tanto a Query SELECT quanto o Comando Pós-Coleta aceitam :nome para as Variáveis (globais e da
Aplicação) e para os Parâmetros de Entrada da Coleta:
SELECT * FROM apontamento WHERE planta = :PLANTA_PADRAO AND turno = :turnoSó os nomes que de fato aparecem no texto são bindados, e o valor vai sempre como parâmetro do driver — nunca concatenado. Em caso de nome repetido, a Variável tem prioridade sobre o Parâmetro de Entrada, igual à resolução dos demais campos.
Não coloque o placeholder entre aspas (':turno'): dentro de um literal ele deixa de ser bind e
vira texto — comparação sempre falsa no SQL Server, erro de bind no Oracle e no PostgreSQL. O CMS
avisa ao salvar.
Entrega — SQL_SERVER_EXEC / ORACLE_EXEC / POSTGRES_EXEC / SQLITE_EXEC
Executa o Comando SQL da Definição de Mensagem no banco destino, com os dados da mensagem. O
comando roda com commit automático, e o retorno (linha(s) afetada(s)) entra no histórico da
mensagem, onde pode ser avaliado por regras de erro de negócio. Quando o banco recusa o comando, o
erro gravado traz junto o comando executado com os valores no lugar dos placeholders — é o que
permite reproduzir a falha direto no cliente SQL.
| Placeholder | Valor |
|---|---|
:payload | Corpo da mensagem como texto |
:datetime | Data/hora do processamento |
:transformer | Saída do Transformador configurado na Entrega |
:NOME | Variável global ou da Aplicação |
:alias | Parâmetro de Entrada |
INSERT INTO recebimento (payload, recebido_em, planta)
VALUES (:payload, :datetime, :PLANTA_PADRAO)Procedures e SQL dinâmico
| Dialeto | Como chamar |
|---|---|
| SQL Server | EXEC minha_procedure :payload, :datetime — procedure nomeada; EXEC(@variavel) e EXEC('texto') são bloqueados |
| SQL Server | EXEC (:transformer) — executa como SQL o texto gerado pelo Transformador |
| Oracle | Só DML (INSERT/UPDATE/DELETE). Para rodar PL/SQL gerado pelo Transformador, use exatamente BEGIN EXECUTE IMMEDIATE :transformer; END; |
| PostgreSQL | Só DML (INSERT/UPDATE/DELETE/MERGE), incluindo INSERT ... ON CONFLICT. CALL de procedure e blocos DO $$...$$ não são aceitos |
| Todos | Comando igual a só :transformer — o texto gerado pelo Transformador é o comando executado |
Chamar procedure Oracle por nome (bloco PL/SQL ou {call proc(...)}) ainda não é suportado:
validar essa sintaxe com a mesma segurança já aplicada ao T-SQL é um desenho à parte. Enquanto
isso, o caminho é gerar o bloco pelo Transformador.
O que o CMS bloqueia nos campos SQL
Todo campo de comando — Query SELECT, Comando Pós-Coleta, Comando SQL da Entrega e Query de Teste —
passa por um guard antes de ser salvo e de novo antes de executar. Ele exige que o comando comece
com um verbo compatível (leitura: SELECT/WITH; escrita: INSERT/UPDATE/DELETE, mais MERGE no PostgreSQL e REPLACE no SQLite), recusa vários
statements encadeados por ; e barra o vocabulário abaixo:
| Alcance | Bloqueado |
|---|---|
| Todos os dialetos | CREATE, ALTER, DROP, TRUNCATE, GRANT, REVOKE, DENY, BACKUP, RESTORE |
| SQL Server | OPENROWSET, OPENQUERY, OPENDATASOURCE, SHUTDOWN, DBCC, procedures sp_/xp_, EXECUTE AS |
| Oracle | UTL_HTTP, UTL_TCP, UTL_SMTP, UTL_FILE, DBMS_SCHEDULER, DBMS_JOB, DBMS_SQL, EXECUTE IMMEDIATE (fora do bloco do Transformador) |
| PostgreSQL | COPY (inclusive COPY ... FROM PROGRAM, que executa shell no servidor), dblink, pg_read_file, pg_write_file, pg_ls_dir, lo_import, lo_export, pg_sleep, pg_terminate_backend |
| SQLite | ATTACH, DETACH, PRAGMA, VACUUM, REINDEX, LOAD_EXTENSION, READFILE, WRITEFILE |
Comentários e literais de string são neutralizados antes da checagem, então esconder uma palavra
proibida dentro de comentário (CRE/**/ATE) ou de string não passa. Toda tentativa bloqueada vira
registro no log de auditoria, com o campo e o motivo.
O guard é defesa em profundidade, não a proteção principal. Quem realmente limita o estrago é a
permissão do usuário configurado na conexão: sem DDL/DCL, e com GRANT EXECUTE só nas procedures
necessárias.