I want to import products through some MYSQL procedures, I simply have the "import_items" table where the items to be imported are located, and I have the products table, and prices that would be where the data would be destined: The data is entered manually up to this table "Import_items" and a procedure will check if the products are duplicates. Below are the declarations of said tables described: Import_items table
CREATE TABLE `importar_items` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`idimportar` INT(11) NOT NULL DEFAULT '0',
`cantidad` DECIMAL(11,2) NULL DEFAULT NULL,
`nombre` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`categoria` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`codigobarras` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`precio` DECIMAL(10,2) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idimportar` (`idimportar`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
Products Table
CREATE TABLE `productos` (
`cantidad` DECIMAL(11,2) NOT NULL DEFAULT '0.00',
`cantidadbultoabierto` DECIMAL(11,2) NULL DEFAULT NULL,
`cantidadbultocerrado` DECIMAL(11,2) NULL DEFAULT NULL,
`categoria` INT(11) NULL DEFAULT NULL,
`eliminado` TINYINT(1) NOT NULL DEFAULT '0',
`especial` TINYINT(1) NOT NULL DEFAULT '0',
`fecha` DATETIME NOT NULL,
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ingresosbrutos` DECIMAL(3,2) NOT NULL DEFAULT '0.00',
`nombre` VARCHAR(250) NOT NULL COLLATE 'utf8_general_ci',
`proveedor` INT(11) NULL DEFAULT NULL,
`stockminimo` DECIMAL(11,2) NOT NULL DEFAULT '4.00',
`tipodeproducto` INT(11) NULL DEFAULT NULL,
`ultimamodificacion` DATETIME NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`balanzaid` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `id` (`id`, `nombre`) USING BTREE,
INDEX `eliminado` (`eliminado`) USING BTREE,
INDEX `ultimamodificacion` (`ultimamodificacion`) USING BTREE,
INDEX `id2` (`id`) USING BTREE,
FULLTEXT INDEX `nombre` (`nombre`),
FULLTEXT INDEX `nombre_2` (`nombre`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
Price Table
CREATE TABLE `precios` (
`ganancia` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
`id` INT(11) NOT NULL AUTO_INCREMENT,
`idproducto` INT(11) NOT NULL DEFAULT '0',
`impuesto` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
`ingresosbrutos` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
`numerodepreciodelista` INT(10) NOT NULL DEFAULT '0',
`porcentaje` DECIMAL(4,2) NOT NULL DEFAULT '0.00',
`precio` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
`precio2` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
`costo` DECIMAL(10,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `id` (`id`) USING BTREE,
INDEX `numerodepreciodelista` (`idproducto`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
The destination tables are "products" and "Prices": The idea of the tables is as follows, each product is detailed in the products table and is identified with products.id and products.name, each product corresponds to a price, from which is related as follows products.id = prices.idproduct. Each product can have multiple prices deferred by Price.listpricenumber. In other words, the product "PAN" has a price of "3" as a list price number 0, and this cannot be repeated, it cannot have two prices Price.listpricenumber=0.
The procedure checks if the product and its price exists and inserts it, and if not, it updates it and here is the problem. The products are added and if they are added, update their name. But the prices are inserted even if they already exist, and not as it should be, which is to update the "Price.price"
Each import is identified with an id_importacion to group the products by process, to differentiate from another in case there is the case that two imports are being done at the same time!
Here is the formula:
/*aquí agrego los productos */
INSERT IGNORE INTO productos (nombre, cantidad, fecha) SELECT nombre, cantidad, CURRENT_TIMESTAMP() FROM importar_items WHERE importar_items.idimportar= ultimoidimportar;
/*aquí actualizo los nombre de los productos por sus codigo de barras*/
update productos a inner JOIN codigobarras b ON (a.id = b.idproducto ) INNER JOIN importar_items c ON c.codigobarras = b.codigobarras set a.nombre = c.nombre where c.idimportar= ultimoidimportar AND c.codigobarras IS NOT NULL;
The question query is as follows:
/*aqui los precios que debo ingresar pero se duplican*/
INSERT IGNORE INTO precios (idproducto, precio) SELECT productos.id, importar_items.precio FROM importar_items , productos WHERE productos.nombre = importar_items.nombre AND importar_items.idimportar= ultimoidimportar AND importar_items.precio IS NOT null;
My idea would be an INSERT INTO prices of idproduct and price of IMPORTAR_ITEMS without them being repeated and the condition of prices.numberofpriceoflist=0 not being repeated. in that case update!
In the event that they exist, it works for me with the following query:
/*actualizo precios*/
update precios u inner JOIN productos c ON (u.idproducto = c.id ) INNER JOIN importar_items d ON d.nombre = c.nombre set u.precio = d.precio where u.numerodepreciodelista = 0 AND d.idimportar= ultimoidimportar AND d.precio IS NOT NULL;
I am entering all the functions that do work so you can see how the import is done.
Is it possible to import the products and prices without duplicating them and in the event that they are found, update product.name and price.price? And to make the procedure faster, can it be done all in one query? to avoid excess query time when importing thousands of products? Well I hope someone can help me Thank you very much in advance
For this there is
INSERT INTO ... ON DUPLICATE KEY UPDATE
Example: