MundoJSnode.jsDicas para Usar Funções e Procedures em Node.js (Guia...

Dicas para Usar Funções e Procedures em Node.js (Guia Definitivo)

Entenda as diferenças entre funções e procedures no Node.js com TypeORM. Aprenda práticas recomendadas e hacks avançados para integrar e gerenciar essas ferramentas no seu banco de dados com eficiência.

-

A arquitetura de uma aplicação backend moderna frequentemente levanta um debate clássico: onde deve residir a lógica de processamento mais pesada? Na camada da aplicação ou diretamente no banco de dados? Embora a tendência atual favoreça manter o controle no código, ignorar o poder nativo do seu banco relacional pode resultar em perda de performance, gargalos de rede e consultas ineficientes.

É exatamente nesse cenário de otimização que aplicar as melhores dicas para usar Funções e Procedures em Node.js se torna um diferencial técnico. Neste guia definitivo, vamos desmistificar o uso dessas estruturas, explorando desde as diferenças fundamentais até hacks avançados de integração com ORMs modernos como TypeORM, Drizzle e Prisma. Se você quer escrever um backend mais seguro, rápido e escalável, este artigo é para você.

Com a popularidade crescente de Node.js e TypeORM, a necessidade de gerenciar funções e procedures no banco de dados de forma eficiente tem se tornado cada vez mais comum. TypeORM, sendo um poderoso ORM (Object-Relational Mapping), oferece suporte para lidar com essas estruturas de maneira organizada e escalável.

Dicas para Usar Funções e Procedures em Node.js

Este artigo explora as diferenças entre funções e procedures no contexto de Node.js e TypeORM, além de boas práticas de versionamento para manter consistência e escalabilidade em seus projetos.


Funções e Procedures no Banco de Dados

Embora funções e procedures sejam criadas e mantidas no banco de dados, sua integração com Node.js e TypeORM pode facilitar sua execução e gerenciamento.

Dica de Leitura: Se você está explorando como melhorar a qualidade e a manutenção do seu código em projetos Node.js, especialmente após entender como lidar com funções e procedures, uma ferramenta como o SonarQube pode ser extremamente útil. Leia nosso artigo sobre Como instalar e configurar SonarQube para projetos Node.js para descobrir como automatizar a análise de código e melhorar a qualidade do seu projeto.

Diferenças Fundamentais

Aspecto Funções Procedures
Uso Principal Retornar valores únicos. Executar operações complexas.
Integração SQL Usadas em consultas SQL. Chamadas por meio de comandos diretos.
Alterações no DB Não alteram o banco diretamente. Podem alterar o banco de dados.
Retorno Retornam valores. Podem retornar múltiplos valores por parâmetros de saída.

Exemplo com Funções

Função SQL para calcular imposto:

CREATE FUNCTION CalculateTax(subtotal DECIMAL(10,2))
RETURNS DECIMAL(10,2)
BEGIN
    RETURN subtotal * 0.2;
END;

Uso no TypeORM:

import { DataSource } from 'typeorm';

const dataSource = new DataSource({
    type: 'mysql',
    host: 'localhost',
    username: 'root',
    password: 'password',
    database: 'example_db',
});

dataSource.initialize().then(async () => {
    const result = await dataSource.query('SELECT CalculateTax(100) AS tax');
    console.log(result); // [{ tax: 20 }]
});

Exemplo com Procedures

Procedure SQL para atualizar estoque:

DELIMITER //
CREATE PROCEDURE UpdateStock(IN product_id INT, IN quantity INT)
BEGIN
    UPDATE inventory SET stock = stock + quantity WHERE id = product_id;
END //
DELIMITER ;

Uso no TypeORM:

await dataSource.query('CALL UpdateStock(?, ?)', [101, 50]);

Quando Usar Funções ou Procedures em Node.js

Funções

Cenários:

  1. Cálculos simples e reutilizáveis.
  2. Manipulação de strings.
  3. Usadas diretamente em consultas SQL.

Vantagens:

  • Simplicidade de uso em SELECT.
  • Compatibilidade com diferentes partes da consulta SQL.

Exemplo Prático com TypeORM

const result = await dataSource.query('SELECT FormatDate(?) AS formatted_date', ['2024-01-01']);
console.log(result); // [{ formatted_date: '01/01/2024' }]

Procedures

Cenários:

  1. Fluxos complexos que envolvem várias etapas.
  2. Alterações no banco de dados (INSERT, UPDATE, DELETE).
  3. Automação de processos repetitivos.

Vantagens:

  • Redução de lógica no backend.
  • Centralização de operações críticas no banco.

Exemplo Prático com TypeORM

await dataSource.query('CALL GenerateMonthlyReport(?, ?)', [12, 2023]);

Evolução dos ORMs – Executando Procedures no Prisma e Drizzle ORM

Enquanto o TypeORM consolidou seu espaço, projetos mais recentes têm adotado alternativas modernas que focam em type-safety extremo, como Drizzle ORM e Prisma. Mostrar como lidar com DB Objects nessas ferramentas agrega muito valor:

  • No Drizzle ORM: Como o Drizzle é muito próximo do SQL puro, a execução de procedures é feita de forma extremamente limpa usando o template literal sql.

    import { sql } from 'drizzle-orm';
    // Chamando uma procedure de atualização de estoque de forma segura
    await db.execute(sql`CALL UpdateStock(${productId}, ${quantity})`);
    
  • No Prisma: O Prisma utiliza o método $executeRaw ou $queryRaw para chamadas diretas ao banco.

    // Executando uma função escalar
    const result = await prisma.$queryRaw`SELECT CalculateTax(${subtotal}) AS tax`;
    

Boas Práticas de Versionamento com Node.js e TypeORM

Gerenciar a evolução de funções e procedures é essencial para evitar problemas em ambientes de produção. Com Node.js e TypeORM, você pode usar ferramentas e estratégias específicas para versionamento.

1. Migrations no TypeORM

O TypeORM suporta migrations, que são scripts para gerenciar alterações no banco de dados.

Exemplo de Migration para Adicionar uma Função

import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddCalculateTaxFunction1681023456789 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            CREATE FUNCTION CalculateTax(subtotal DECIMAL(10,2))
            RETURNS DECIMAL(10,2)
            BEGIN
                RETURN subtotal * 0.2;
            END;
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query('DROP FUNCTION IF EXISTS CalculateTax');
    }
}

2. Script de Rollback

Sempre inclua um script para reverter alterações.

Exemplo:

export class AddUpdateStockProcedure1681023456790 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            CREATE PROCEDURE UpdateStock(IN product_id INT, IN quantity INT)
            BEGIN
                UPDATE inventory SET stock = stock + quantity WHERE id = product_id;
            END;
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query('DROP PROCEDURE IF EXISTS UpdateStock');
    }
}

3. Documentação e Comentários

  • Documente o propósito e as alterações de cada função ou procedure.
  • Use comentários nos arquivos de migration.

4. Teste Automatizado de Funções e Procedures

  • Execute testes diretamente no banco usando ferramentas como Jest.

Exemplo de Teste com Jest:

import { DataSource } from 'typeorm';

describe('Database Functions', () => {
    let dataSource: DataSource;

    beforeAll(async () => {
        dataSource = new DataSource({ /* Configurações */ });
        await dataSource.initialize();
    });

    afterAll(async () => {
        await dataSource.destroy();
    });

    it('should calculate tax correctly', async () => {
        const result = await dataSource.query('SELECT CalculateTax(100) AS tax');
        expect(result[0].tax).toBe(20);
    });
});

5. Automação com CI/CD

  • Integre migrations e testes de banco em pipelines CI/CD (e.g., Jenkins, GitHub Actions).
  • Execute migrations antes de publicar novas versões.

Hacks Avançados

1. Usar Parâmetros Dinâmicos em Funções

Crie funções flexíveis com parâmetros opcionais.

CREATE FUNCTION CalculateTaxDynamic(subtotal DECIMAL(10,2), rate DECIMAL(5,2) DEFAULT 0.2)
RETURNS DECIMAL(10,2)
BEGIN
    RETURN subtotal * rate;
END;

2. Combinar Funções com Views

Simplifique consultas complexas usando funções dentro de views.

CREATE VIEW monthly_sales AS
SELECT
    MONTH(sale_date) AS month,
    YEAR(sale_date) AS year,
    CalculateTax(SUM(total)) AS tax
FROM sales
GROUP BY MONTH(sale_date), YEAR(sale_date);

3. Monitoramento de Funções e Procedures

Armazene metadados de uso:

CREATE TABLE function_usage (
    id INT AUTO_INCREMENT PRIMARY KEY,
    function_name VARCHAR(255),
    called_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Adicione tracking nas migrations:

await queryRunner.query(`
    CREATE TRIGGER track_function_usage
    AFTER CALL ON CalculateTax
    FOR EACH ROW
    BEGIN
        INSERT INTO function_usage (function_name) VALUES ('CalculateTax');
    END;
`);

Característica Função (Function) Procedimento (Procedure)
Objetivo Principal Cálculos e retorno de um único valor ou tabela. Processamento em lote e rotinas complexas.
Alteração de Dados (DML) Restrito Normalmente não pode usar INSERT/UPDATE. Permitido Pode alterar múltiplos registros facilmente.
Chamada no Node.js Dentro de declarações SELECT. Através do comando CALL ou EXEC.
Uso em Views SQL Sim, podem ser integradas diretamente em Views. Não é possível utilizar dentro de Views.
Retorno de Dados Obrigatório (Escalar ou Table). Opcional (Pode usar parâmetros OUT).

Perguntas Frequentes (FAQ)

É melhor usar TypeORM, Prisma ou Drizzle para executar Procedures no Node.js?

Todos suportam a execução de Procedures, mas através de raw queries (consultas diretas). O Drizzle ORM oferece uma sintaxe muito mais leve e próxima ao SQL puro com seu template literal (sql), enquanto o TypeORM utiliza o método dataSource.query() para realizar o comando CALL.

Funções SQL podem causar problemas de performance no Node.js?

Sim. Se a função for muito complexa e for chamada repetidas vezes dentro de loops no Node.js ou aplicada a milhões de linhas em um SELECT sem índices, ela criará um gargalo de processamento no banco de dados, impactando o tempo de resposta da sua API.

Como proteger a execução de Procedures contra SQL Injection em Node.js?

Nunca concatene strings ao passar variáveis para uma Procedure. Utilize sempre consultas parametrizadas. No TypeORM, passe as variáveis como um array no segundo argumento do método query: dataSource.query(‘CALL UpdateStock(?, ?)’, [id, quantidade]).

Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade dedicado a linguagens de programação, banco de dados, DevOps, Internet das Coisas (IoT), tecnologias da Indústria 4.0, cibersegurança e startups. Com curadoria de conteúdos de qualidade, o projeto é mantido por Ramos de Souza Janones.

Mais recentes

Como aprender a programar, um guia definitivo

Última atualização em 23/04/2026. Guia completo sobre: Como aprender a programar. Espero que este “guia” ou “manifesto”, como prefiro chamar, seja...

Stream Deck para Desenvolvedores: o Console de Comando do Futuro

Esqueça os streamers. Descubra como o Stream Deck se tornou o hardware essencial para Engenheiros de IA e Full...

Como Usar o Skills in Chrome no Brasil: Tutorial Completo de IA

A inteligência artificial já faz parte do nosso fluxo de trabalho, mas ter que reescrever os mesmos prompts repetidamente...

Context Engineering: Como Arquitetar Dados para LLMs e RAG

Na edição desta newsletter intitulada “Engenharia de Prompt: Não é só mais uma buzzword“: https://www.linkedin.com/pulse/engenharia-de-prompt-n%C3%A3o-%C3%A9-s%C3%B3-mais-uma-buzzword-de-souza-janones-tpkxf tratei sobre o tema...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Aprender Idiomas com Google Tradutor: Na Prática

O Google está lançando um novo recurso experimental com tecnologia de IA no Google Tradutor, projetado para ajudar as...

Comunidades Internacionais de Desenvolvedores

Descubra as melhores comunidades internacionais de devs para 2026: GitHub, Stack Overflow, Discord e mais. Comparativo de salários Brasil vs. exterior e guia de carreira remota.

Mais Lidos

SQL WHERE 1: O que é e por que usar o truque do WHERE 1=1?

Entenda o que significa WHERE 1 (ou WHERE 1=1)...

O Fim do WordPress? Veja 6 Alternativas para Migrar

No dia 11 de janeiro de 2025, Gavin Anderegg...

Sprint SQL: Planeje e Execute como um Pro (Guia Definitivo)

Do dia 24 de Outubro até o dia 12...

Setup para Programadores: A Estação de Trabalho Eficiente

A configuração de uma estação de trabalho eficiente é...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Você vai gostarrelacionados
Continue aprendendo

E-Zine Dev Ramos

Quer dominar arquitetura e IA?

Junte-se a +10.000 profissionais. Receba semanalmente estratégias de Node.js, React e IA que nunca publicamos no blog.

Assinar Gratuitamente Zero spam. Cancele quando quiser.