POSTGRESQL UPDATE - Atualizar Registro
O que é este Node?
O POSTGRESQL UPDATE é o node responsável por atualizar registros existentes em tabelas PostgreSQL de forma segura usando prepared statements.
Por que este Node existe?
Atualizar dados é operação essencial em aplicações. O POSTGRESQL UPDATE existe para:
- Segurança: Usa prepared statements prevenindo SQL injection
- Condicional: Atualiza apenas registros que atendem condições WHERE
- Múltiplos campos: Atualiza vários campos em uma única operação
- RETURNING: Retorna registros atualizados com novos valores
- Validação: Valida campos antes de executar
- Performance: Otimizado para updates estruturados
Como funciona internamente?
Quando o POSTGRESQL UPDATE é executado, o sistema:
- Valida config: Verifica credenciais PostgreSQL
- Substitui variáveis: Troca {{variavel}} em values e conditions
- Monta SQL: Cria UPDATE com placeholders ($1, $2...) seguros
- Aplica WHERE: Adiciona cláusula WHERE com conditions
- Executa: Envia para PostgreSQL com valores parametrizados
- Retorna: Devolve registros atualizados (RETURNING *) e rowCount
- Se erro: Lança exceção (registro não existe, constraint violation)
Código interno (postgresql.executor.ts:126-154):
private async updateRow(
pool: Pool,
table: string,
fields: string[],
values: Record<string, any>,
conditions: Record<string, any>,
context: ExecutionContext,
): Promise<any> {
const replacedValues = this.replaceObjectVariables(values, context.variables);
const replacedConditions = this.replaceObjectVariables(conditions, context.variables);
const setClause = Object.keys(replacedValues)
.map((key, i) => `${key} = $${i + 1}`)
.join(', ');
const whereClause = Object.keys(replacedConditions)
.map((key, i) => `${key} = $${Object.keys(replacedValues).length + i + 1}`)
.join(' AND ');
const valueArray = [...Object.values(replacedValues), ...Object.values(replacedConditions)];
const query = `UPDATE ${table} SET ${setClause} WHERE ${whereClause} RETURNING *`;
const result = await pool.query(query, valueArray);
return {
updatedRows: result.rows,
rowCount: result.rowCount,
};
}
Quando você DEVE usar este Node?
Use POSTGRESQL UPDATE quando precisar atualizar registros existentes:
Casos de uso
- Atualizar perfil: "Alterar email ou telefone de cliente"
- Mudar status: "Marcar pedido como 'enviado'"
- Incrementar contador: "Aumentar visualizações de produto"
- Corrigir dados: "Ajustar informações incorretas"
- Atualização condicional: "Modificar apenas registros específicos"
Quando NÃO usar POSTGRESQL UPDATE
- Registro pode não existir: Use POSTGRESQL INSERTORUPDATE (upsert)
- Query complexa: Use POSTGRESQL EXECUTEQUERY para UPDATE com subconsultas
- Múltiplos registros com lógica: Use EXECUTEQUERY com CASE WHEN
- Sem condições: NUNCA update sem WHERE (atualizaria tudo!)
Parâmetros Detalhados
config (object, obrigatório)
O que é: Configuração de conexão com PostgreSQL.
Estrutura:
{
"host": "localhost",
"port": 5432,
"database": "nome_database",
"user": "usuario",
"password": "senha",
"ssl": false
}
table (string, obrigatório)
O que é: Nome da tabela onde registros serão atualizados.
values (object, obrigatório)
O que é: Campos e novos valores a serem definidos.
Formato: { "campo1": "novo_valor", "campo2": 456 }
conditions (object, obrigatório)
O que é: Condições WHERE para identificar quais registros atualizar.
Formato: { "id": 123 } ou { "email": "jose@example.com", "ativo": true }
IMPORTANTE: Todas as condições são combinadas com AND
Flow completo para testar:
{
"name": "Teste PostgreSQL - Update",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "ID Cliente",
"parameters": {
"message": "ID do cliente a atualizar:",
"variable": "clienteId"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Novo Email",
"parameters": {
"message": "Novo email:",
"variable": "novoEmail"
}
}
},
{
"id": "postgres_1",
"type": "postgresql",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Atualizar Email",
"parameters": {
"operation": "update",
"config": {
"host": "localhost",
"port": 5432,
"database": "crm",
"user": "app_user",
"password": "secure_password",
"ssl": false
},
"table": "clientes",
"values": {
"email": "{{novoEmail}}",
"data_atualizacao": "CURRENT_TIMESTAMP"
},
"conditions": {
"id": "{{clienteId}}"
},
"responseVariable": "resultado"
}
}
},
{
"id": "condition_1",
"type": "condition",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Atualizado?",
"parameters": {
"conditions": [
{
"variable": "resultado.rowCount",
"operator": "greater_than",
"value": 0,
"nextNode": "message_success"
}
],
"defaultNextNode": "message_notfound"
}
}
},
{
"id": "message_success",
"type": "message",
"position": { "x": 1100, "y": 50 },
"data": {
"label": "Sucesso",
"parameters": {
"message": "Email atualizado com sucesso!\n\nNovo email: {{novoEmail}}"
}
}
},
{
"id": "message_notfound",
"type": "message",
"position": { "x": 1100, "y": 150 },
"data": {
"label": "Não Encontrado",
"parameters": {
"message": "Cliente com ID {{clienteId}} não foi encontrado."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "postgres_1" },
{ "source": "postgres_1", "target": "condition_1" },
{ "source": "message_success", "target": "end_1" },
{ "source": "message_notfound", "target": "end_1" }
]
}
Teste: Registro é atualizado se existir, senão retorna rowCount = 0.
responseVariable (string, opcional)
O que é: Nome da variável para armazenar resultado no contexto.
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "update" |
| config | object | Sim | Configuração de conexão PostgreSQL |
| table | string | Sim | Nome da tabela |
| values | object | Sim | Campos e valores a atualizar |
| conditions | object | Sim | Condições WHERE (combinadas com AND) |
| responseVariable | string | Não | Variável para armazenar resultado |
Exemplo 1: Atualizar Status de Pedido
Objetivo: Mudar status de pedido para 'enviado' após despacho
JSON para Importar
{
"name": "PostgreSQL - Atualizar Status Pedido",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Número Pedido",
"parameters": {
"message": "Número do pedido despachado:",
"variable": "pedidoId"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Código Rastreio",
"parameters": {
"message": "Código de rastreio:",
"variable": "codigoRastreio"
}
}
},
{
"id": "postgres_1",
"type": "postgresql",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Atualizar Pedido",
"parameters": {
"operation": "update",
"config": {
"host": "localhost",
"port": 5432,
"database": "ecommerce",
"user": "app_user",
"password": "secure_password",
"ssl": false
},
"table": "pedidos",
"values": {
"status": "enviado",
"codigo_rastreio": "{{codigoRastreio}}",
"data_envio": "CURRENT_TIMESTAMP"
},
"conditions": {
"id": "{{pedidoId}}",
"status": "pendente"
},
"responseVariable": "resultado"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmação",
"parameters": {
"message": "Pedido {{pedidoId}} atualizado!\n\nStatus: Enviado\nCódigo de Rastreio: {{codigoRastreio}}\n\n{{resultado.rowCount}} pedido(s) atualizado(s)."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "input_2" },
{ "source": "input_2", "target": "postgres_1" },
{ "source": "postgres_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Número do pedido despachado:
Usuário: 1523
Sistema: Código de rastreio:
Usuário: BR123456789BR
Sistema: Pedido 1523 atualizado!
Status: Enviado
Código de Rastreio: BR123456789BR
1 pedido(s) atualizado(s).
Exemplo 2: Atualizar Perfil Completo
Objetivo: Permitir cliente atualizar múltiplos campos do perfil
JSON para Importar
{
"name": "PostgreSQL - Atualizar Perfil",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Menu",
"parameters": {
"message": "Atualização de Perfil\n\nVamos atualizar seus dados."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Novo Nome",
"parameters": {
"message": "Novo nome completo:",
"variable": "novoNome"
}
}
},
{
"id": "phone_1",
"type": "phone",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Novo Telefone",
"parameters": {
"message": "Novo telefone:",
"variable": "novoTelefone"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Nova Cidade",
"parameters": {
"message": "Nova cidade:",
"variable": "novaCidade"
}
}
},
{
"id": "postgres_1",
"type": "postgresql",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Salvar Alterações",
"parameters": {
"operation": "update",
"config": {
"host": "localhost",
"port": 5432,
"database": "crm",
"user": "app_user",
"password": "secure_password",
"ssl": false
},
"table": "clientes",
"values": {
"nome": "{{novoNome}}",
"telefone": "{{novoTelefone}}",
"cidade": "{{novaCidade}}",
"data_atualizacao": "CURRENT_TIMESTAMP"
},
"conditions": {
"id": "{{phone}}"
},
"responseVariable": "resultado"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Sucesso",
"parameters": {
"message": "Perfil atualizado com sucesso!\n\nNome: {{novoNome}}\nTelefone: {{novoTelefone}}\nCidade: {{novaCidade}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "phone_1" },
{ "source": "phone_1", "target": "input_2" },
{ "source": "input_2", "target": "postgres_1" },
{ "source": "postgres_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Atualização de Perfil
Vamos atualizar seus dados.
Sistema: Novo nome completo:
Usuário: José Roberto Silva Oliveira
Sistema: Novo telefone:
Usuário: 11999887766
Sistema: Nova cidade:
Usuário: Rio de Janeiro
Sistema: Perfil atualizado com sucesso!
Nome: José Roberto Silva Oliveira
Telefone: 11999887766
Cidade: Rio de Janeiro
Resposta do Node
{
"updatedRows": [
{
"id": 42,
"nome": "José Roberto Silva Oliveira",
"email": "jose@example.com",
"telefone": "11999887766",
"cidade": "Rio de Janeiro",
"data_atualizacao": "2025-01-15T15:45:00.000Z",
"ativo": true
}
],
"rowCount": 1
}
Boas Práticas
✅ SIM:
- SEMPRE use conditions (WHERE) para evitar atualizar toda tabela
- Valide dados antes de atualizar
- Use CURRENT_TIMESTAMP para campos de auditoria
- Verifique rowCount para confirmar atualização
- Capture updatedRows para ver valores finais
- Use transações para múltiplos updates relacionados
❌ NÃO:
- NUNCA update sem WHERE (conditions obrigatório!)
- Não atualize chaves primárias
- Não ignore rowCount = 0 (registro não existe)
- Não atualize sem validar formato
- Não atualize campos calculados (recalcule)
- Não use UPDATE quando INSERT é necessário
Dicas
💡 RETURNING: PostgreSQL retorna registros atualizados com novos valores
💡 rowCount = 0: Significa que nenhum registro atendeu conditions (não existe)
💡 Múltiplas conditions: Todas são combinadas com AND automaticamente
💡 Timestamps: Use CURRENT_TIMESTAMP para campos de auditoria
💡 Optimistic locking: Adicione version ou updated_at em conditions para evitar conflitos
💡 Partial updates: Atualize apenas campos necessários (não precisa de todos)
💡 Condições complexas: Para OR ou subconsultas, use EXECUTEQUERY
Próximo Node
→ POSTGRESQL DELETE - Deletar registros → POSTGRESQL INSERT - Inserir registros → POSTGRESQL INSERTORUPDATE - Upsert (Insert ou Update) → POSTGRESQL EXECUTEQUERY - Consultas personalizadas