El FROM
parte del SELECT
la declaración debe tener nombres de tablas reales, no un CHAR(100)
variable que contiene el nombre de la tabla. Simplemente no funciona así.
Parece que desea ejecutar una consulta particular en muchas tablas con una estructura similar en su base de datos. Muy a menudo significa que el esquema de la base de datos podría mejorarse. Pero, si tiene que lidiar con lo que tiene, tendrá que usar SQL dinámico . Este enlace a la documentación de MySQL tiene un ejemplo "que demuestra cómo elegir la tabla en la que realizar una consulta en tiempo de ejecución, almacenando el nombre de la tabla como una variable de usuario", que es exactamente lo que necesita.
Dentro de su bucle, debe crear una cadena con la consulta SQL y usar EXECUTE
.
SET @s = CONCAT('select count(distinct signature) from ', tableName);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Según tengo entendido, el resultado de EXECUTE
se envía a la persona que llama del procedimiento almacenado como si fuera un SELECT
normal , por lo que en este ejemplo, la persona que llama recibirá varios conjuntos de resultados si su base de datos tiene más de una tabla where table_name like "%FAULT_20150320%"
.
Aquí hay un enlace a otra pregunta SO sobre MySQL SQL dinámico Cómo tener SQL dinámico en el procedimiento almacenado de MySQL con algunos ejemplos.
Parece que quieres algo como esto. Debe resumir los recuentos de varias tablas en signatureCount
variables.
CREATE PROCEDURE CountSignatures()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE signatureCount INT;
DECLARE tableName CHAR(100);
DECLARE tableList CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_name LIKE "%FAULT_20150320%";
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET signatureCount = 0;
OPEN tableList;
tableListLoop: LOOP
SET done = FALSE;
FETCH tableList INTO tableName;
IF done THEN
LEAVE tableListLoop;
END IF;
SET @VarCount = 0;
SET @VarSQL = CONCAT('SET @VarCount = (SELECT COUNT(DISTINCT signature) FROM ', tableName, ')');
PREPARE stmt FROM @VarSQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET signatureCount = signatureCount + @VarCount;
END LOOP;
CLOSE tableList;
SELECT signatureCount;
END$$
Otra variante, si la cantidad de tablas que necesita procesar no es mucha, es construir dinámicamente una declaración SQL grande que incluya todas las tablas dentro de su ciclo y luego EXECUTE
de una vez:
SELECT
(COUNT(DISTINCT signature) FROM Table1) +
(COUNT(DISTINCT signature) FROM Table2) +
...
(COUNT(DISTINCT signature) FROM TableN) AS TotalCount