Problema con un insert en un procedimiento almacenado.

hadrien
05 de Mayo del 2008
Hola,

estoy intentando manejar particiones con MySQL 5.0 mediante lo que se llama "el método de la vieja escuela" para hacer unas pruebas de rendimiento.
Cuando hago pruebas insertando datos me da un error y no sé muy bien cómo solucionarlo.

Tengo el siguiente procedimiento:
DELIMITER //
CREATE PROCEDURE insert_file (
IN idfile BIGINT UNSIGNED,
IN guid VARCHAR(32),
IN name VARCHAR(128),
IN size BIGINT UNSIGNED,
IN `checksum` VARCHAR(32),
IN `user` SMALLINT UNSIGNED,
IN `group` TINYINT UNSIGNED,
IN permits TINYINT UNSIGNED,
IN dir BIGINT UNSIGNED
)
BEGIN
DECLARE n BIGINT DEFAULT 0;
IF idfile < 10000 THEN
IF ( ( idfile MOD 2000 = 0 ) AND ( NOT(idfile=2000) ) ) THEN
SET n = ( idfile DIV 5000 ) - 1;
ELSE
SET n = idfile DIV 5000;
END IF;
ELSE
SET n = 2000;
END IF;
SET @stmt = CONCAT('INSERT INTO file_p',n,' VALUES (',
idfile,',',guid,',',name,',',size,',',`checksum`,',',`user`,',',`group`,',',permits,',',dir,')');
PREPARE stmt FROM @stmt;
EXECUTE stmt;
END;
//
DELIMITER ;

Pero cuando intento introducir valores:
CALL insert_file(1,'123','/proves.txt',45,'gfretgfe45',2,3,1,1);

Me da este error:
ERROR 1064 (42000) at line 25: You have an error in your SQL syntax; check the m
anual that corresponds to your MySQL server version for the right syntax to use
near '/proves.txt,45,gfretgfe45,2,3,1,1)' at line 1

Y no sé cómo arreglarlo, imagino que debe ser un problema de con los carácteres ` o bien con los varchar, pero no lo veo...

El comando "show create table" me da:
mysql> show create table file G
*************************** 1. row **********************
Table: file
Create Table: CREATE TABLE `file` (
`idfile` bigint(20) unsigned NOT NULL auto_increment,
`guid` varchar(32) NOT NULL,
`name` varchar(128) NOT NULL,
`size` bigint(20) unsigned NOT NULL default '0',
`checksum` varchar(32) NOT NULL default '',
`user` smallint(5) unsigned NOT NULL default '0',
`group` tinyint(3) unsigned NOT NULL default '0',
`permits` tinyint(3) unsigned NOT NULL default '0',
`dir` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`idfile`),
UNIQUE KEY `guid` (`guid`),
UNIQUE KEY `trelation` (`name`,`dir`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

Saludos y gracias.

hadrien
05 de Mayo del 2008
Hola,

alguien me aconsejó que hiciera algo como esto:

DELIMITER //
CREATE PROCEDURE insert_file (
IN idfile BIGINT UNSIGNED,
IN guid VARCHAR(32),
IN name VARCHAR(128),
IN size BIGINT UNSIGNED,
IN `checksum` VARCHAR(32),
IN `user` SMALLINT UNSIGNED,
IN `group` TINYINT UNSIGNED,
IN permits TINYINT UNSIGNED,
IN dir BIGINT UNSIGNED
)
BEGIN
DECLARE n BIGINT DEFAULT 0;
IF idfile < 10000 THEN
IF ( ( idfile MOD 2000 = 0 ) AND ( NOT(idfile=2000) ) ) THEN
SET n = ( idfile DIV 5000 ) - 1;
ELSE
SET n = idfile DIV 5000;
END IF;
ELSE
SET n = 2000;
END IF;
SET @fp = CONCAT("file_p",n);
INSERT INTO @fp VALUES (idfile,guid,name,size,`checksum`,`user`,`group`,permits,dir);
END;
//
DELIMITER ;

Pero tampoco me funciona.

En cualquier caso, no importa porque ya no lo necesito. Ahora la duda que tengo es que no puedo usar dos veces un valor NEW en un trigger:

DELIMITER //
CREATE TRIGGER dir_part BEFORE INSERT ON directory
FOR EACH ROW
BEGIN
IF NEW.iddir > 10000 THEN
INSERT INTO directory_p2 VALUES (NEW.iddir,NEW.idPare,NEW.dname);
ELSEIF NEW.iddir > 5000 THEN
INSERT INTO directory_p1 VALUES (NEW.iddir,NEW.idPare,NEW.dname);
ELSE
INSERT INTO directory_p0 VALUES (NEW.iddir,NEW.idPare,NEW.dname);
END IF;

INSERT INTO dptree VALUES(NEW.iddir,NEW.idPare,NEW.dname);
END //
DELIMITER ;

En el último INSERT, el NEW.iddir siempre me lo pone a 0... He probado con SET @id = NEW.iddir, pero nada.

hadrien
05 de Mayo del 2008
De momento lo que solucionado haciendo que la columna iddir sea un índice auto_increment. De esta forma sí me funciona, aunque me parece algo chapucero...