Cómo generar un UID personalizado único, bien formado y legible para SQL (tuplas)
A veces, todos necesitamos una identificación bien formada en lugar de usar la identificación única de número entero en serie generada automáticamente por defecto de 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)
Pero no quiero usar la identificación de serie generada automáticamente. Entonces, primero crearemos un patrón de identificación para la muestra.
Supongamos que tenemos una tabla de agentes con columnas como (agent_id, first_name y last_name), estas columnas las elijo para fines de instancia.
Cada agente tendrá una identificación de agente única.
Fórmula : Iniciales+año(últimos_dos_números)+mes(01..09, 10, 11, 12)+Contador(0000)
ejemplo: AG22120001
Concepto :
AG : es un código que denota agente(s).
Año y Mes: se utiliza con fines de combinación, lo que significa que podemos crear un gran conjunto de combinaciones para las identificaciones de los agentes.
Nota : utilice el último mes y el último año.
Contador : estoy usando un contador 0000 (4 dígitos). El contador se incrementará en +1 cada vez que se cree un nuevo agente.
Ejemplos : 0001…0009…0010…0099…0100…0999…1000
Nota : el contador se restablecerá cuando comience el nuevo mes. Significa que si el mes actual es diciembre (12) y cuando comienza enero, el sistema reinicia automáticamente el contador.
Month(12) -> 0100 — detenemos el incremento si se cambia un mes
Mes(01) -> 0000 — el contador volverá a empezar desde 0
Entonces, cómo se ve,
AG22120100 — el pasado diciembre — 2022
AG23010001 — en el nuevo mes enero — 2023.
Cuando comience Feb(02)-2023 , nuevamente el contador se restablecerá.
Espero que entiendas mi punto. intentemos lograr esto con 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;
Ahora debajo está el código fuente, por favor trate de entender el 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: cree dos tablas 1) agentes y 2) "uid". Estoy usando PostgreSQL para demostración.
-- 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)