Como gerar um UID exclusivo, bem formado e legível personalizado para SQL (Tuples)
À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)