Como gerar um UID exclusivo, bem formado e legível personalizado para SQL (Tuples)

Dec 04 2022
Às vezes, todos nós precisamos de um ID bem formado em vez de usar o ID exclusivo de inteiro serial gerado automaticamente por padrão do SQL. Mas não quero usar o ID serial gerado automaticamente.

Às vezes, todos nós precisamos de um ID bem formado em vez de usar o ID exclusivo de inteiro serial gerado automaticamente por padrão do SQL.

iorta_demo=# SELECT * FROM kpi_fields;
 id |             field_name             | status |         created_at         
----+------------------------------------+--------+----------------------------
 11 | Total GWP in ₹ Lac                 | 1      | 2022-11-30 23:24:23.113146
 12 | Total GWP Retention in ₹           | 1      | 2022-11-30 23:25:01.880207
 13 | % Issuance                         | 1      | 2022-11-30 23:25:14.208774
 14 | Issuance %                         | 1      | 2022-11-30 23:25:57.056154
 15 | Issuance                           | 1      | 2022-11-30 23:26:38.292793
 16 | Pendancy(GWP Pendancy vs. GWP Ach) | 1      | 2022-11-30 23:26:54.969397
 17 | Pendancy                           | 1      | 2022-11-30 23:28:05.264689
(7 rows)

Mas não quero usar o ID serial gerado automaticamente. Primeiro, criaremos um padrão de id para a amostra.

Portanto, suponha que tenhamos uma tabela de agentes com colunas como (agent_id, first_name e last_name) essas colunas que escolhi para fins de instância.

Cada agente terá um ID de agente exclusivo.

Fórmula : Initials+year(last_two_no's)+month(01..09, 10, 11, 12)+Counter(0000)

exemplo: AG22120001

Conceito :

AG — é um código que denota agente(s).

Ano e mês — é usado para fins de combinações, o que significa que podemos criar um grande conjunto de combinações para IDs de agentes.

Nota : Use o último mês e os últimos anos.

Contador : Estou usando um contador de 0000 (4 dígitos). O contador será incrementado em +1 toda vez que um novo agente for criado.

Exemplos : 0001…0009…0010…0099…0100…0999…1000

Nota : O contador será zerado quando o novo mês começar. Isso significa que se o mês atual for dezembro (12) e quando janeiro começar, o sistema redefinirá automaticamente o contador.

Mês(12) -> 0100 — paramos a incrementação se um mês for alterado

Mês(01) -> 0000 — o contador começará novamente a partir de 0s

Então, como parece,

AG22120100 — em dezembro passado — 2022

AG23010001 — no novo mês janeiro — 2023.

Quando fevereiro (02)-2023 começar, novamente o contador será redefinido.

Espero que você entenda meu ponto. vamos tentar conseguir isso com Javascript.

Algoritmo:

Algorithm

1) D <- new Date()
2) latest_year <- D.getFullYear()
3) latest_month <- D.getMonth() + 1
4) last_index <- obj.last_updated_index
5) month <- obj.month
6) IF latest_month == month THEN
      last_index <- last_index + 1
   ELSE
      // Reset indexing for new month
      last_index <- 1;
7) // append 0 if month is single digit
   latest_month = latest_month < 10 ? '0'+latest_month : latest_month
8) // handle 4 digit counter using condition
    IF last_index < 10 THEN
        last_index = '000'+last_index
    ELSE IF last_index >= 10 AND last_index < 100 THEN
        last_index = '00'+last_index
    ELSE IF last_index >= 100 && last_index < 1000 THEN
        last_index = '0'+last_index

9) // Remove first 2 digit from year
    latest_year = latest_year.toString().slice(2);
10) // Combine all in a single string
    id <- AG+latest_year+latest_month+last_index;

Agora abaixo está o código-fonte, por favor, tente entender o código.

// Initialization is required
let cache = {
  last_updated_index: 1,
  month: 12 // I used current month
};

function generateUID() {
  let _calendar_ = new Date();
  let latest_year = _calendar_.getFullYear();
  let latest_month = _calendar_.getMonth() + 1;
  let last_index = cache.last_updated_index;
  let month = cache.month;
  if (latest_month === month) {
    last_index = last_index + 1;
  } else {
    cache.month = latest_month;
    cache.last_updated_index = 1;
    last_index = 1;
  }
  latest_month = latest_month < 10 ? '0' + latest_month : latest_month;
  if (last_index < 10) {
    last_index = '000' + last_index
  } else if (last_index >= 10 && last_index < 100) {
    last_index = '00' + last_index
  } else if (last_index >= 100 && last_index < 1000) {
    last_index = '0' + last_index
  }
  latest_year = latest_year.toString().slice(2);
  return 'AG' + latest_year + latest_month + last_index;
}
let txt = '';
// this loop is just for testing, or demonstration
for (let i = 0; i < 10; i++) {
  let i = generateUID();
  cache.last_updated_index += 1;
  txt += i + " | "
}
console.log(txt);

/* Output
AG22120001
AG22120002
AG22120003
AG22120004
AG22120005
AG22120006
AG22120007
AG22120008
AG22120009
AG22120010
*/

Requisito: Crie duas tabelas 1) agentes e 2) “uid”. Estou usando o PostgreSQL para demonstração.

-- uid for storing last index - like a cache
CREATE TABLE uid(
  last_index INT,
  current_month INT,
  last_updated TIMESTAMP
);

INSERT INTO uid (last_index, current_month, last_updated)
VALUES (1, 12, current_timestamp)

SELECT * FROM uid;

 last_index | current_month |        last_updated        
------------+---------------+----------------------------
          1 |            12 | 2022-12-03 22:10:03.746067
(1 row)

-- Agent table
CREATE TABLE agents(
  agent_id VARCHAR(10) PRIMARY KEY,
  first_name VARCHAR(50),
  last_name  VARCHAR(50)
);

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

const Pool = require('pg').Pool
const pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: '<YOUR_DB_NAME>',
  password: '<YOUR_PASSWORD>',
  port: 5432,
})

app.use(bodyParser.json());
app.use(
  bodyParser.urlencoded({
    extended: true,
  })
);

app.post('/add-agent', (req, res) => {
  let first_name = req.body.firstName;
  let last_name = req.body.lastName;

  // You can create seprate file for that
  pool.query('SELECT * FROM uid', (error, result) => {
    if (error) {
      console.log("Error ", error)
      res.status(500).send({
        CODE: 'ERROR',
        TXT: error.message
      });
      return;
    }

    let _calendar_ = new Date();
    let latest_year = _calendar_.getFullYear();
    let latest_month = _calendar_.getMonth() + 1;

    let last_index = result.rows[0].last_index;
    let month = result.rows[0].current_month;

    if (month == latest_month) {
      last_index += 1;
    } else {
      const updateQuery = `UPDATE uid SET current_month = ${latest_month}, last_index = 1`;
      pool.query(updateQuery, (error) => {
        if (!error) {
          console.log("UID is updated successfully");
        } else {
          console.error(error.stack)
        }
      });
      last_index = 1;
    }

    latest_month = latest_month < 10 ? '0' + latest_month : latest_month;
    if (last_index < 10) {
      last_index = '000' + last_index
    } else if (last_index >= 10 && last_index < 100) {
      last_index = '00' + last_index
    } else if (last_index >= 100 && last_index < 1000) {
      last_index = '0' + last_index
    }

    latest_year = latest_year.toString().slice(2);
    // =========================== please try to seprate it=============
    let newAgentID = 'AG' + latest_year + latest_month + last_index;
    const insertQuery = `
    INSERT INTO agents(
      agent_id,
      first_name,
      last_name
    ) VALUES ($1, $2, $3)
    RETURNING *;
    `;

    pool.query(insertQuery, [
      newAgentID,
      first_name,
      last_name
    ], (error, result) => {
      if (error) {
        console.error(error.stack)
        res.status(500).send({
          CODE: 'ERROR',
          TXT: error.message
        });
      } else {
        const updateQuery = `UPDATE uid SET last_index = last_index + 1`;
        pool.query(updateQuery, (error) => {
          if (!error) {
            console.log("UID is updated successfully")
          } else {
            console.error(error.stack)
          }
        });
        res.status(200).send({
          CODE: 'SUCCESS',
          TXT: result.rows
        });
      }
    });
  })
});

const PORT = 5025;
app.listen(PORT, () => {
  console.log("Server started successfully on " + PORT);
})
curl --location --request POST '127.0.0.1:5025/add-agent' \
--header 'Content-Type: application/json' \
--data-raw '{
    "firstName": "jon",
    "lastName": "smith"
}'
SELECT * FROM agents;
  agent_id  | first_name | last_name 
------------+------------+-----------
 AG22120002 | rahul      | soni
 AG22120003 | pankaj     | k
 AG22120004 | jon        | smith
(3 rows)


-- uid table
SELECT * FROM uid;
 last_index | current_month |        last_updated        
------------+---------------+----------------------------
          4 |            12 | 2022-12-03 22:10:03.746067
(1 row)