FROM
một phần của SELECT
câu lệnh phải có tên bảng thực tế, không phải là CHAR(100)
biến có chứa tên của bảng. Nó không hoạt động như thế này.
Có vẻ như bạn muốn chạy một truy vấn cụ thể với nhiều bảng có cấu trúc tương tự trong cơ sở dữ liệu của mình. Khá thường xuyên, điều đó có nghĩa là lược đồ cơ sở dữ liệu có thể được cải thiện. Tuy nhiên, nếu bạn phải giải quyết những gì bạn có, bạn sẽ phải sử dụng SQL động . Liên kết đến tài liệu MySQL này có một ví dụ "trình bày cách chọn bảng để thực hiện truy vấn trong thời gian chạy, bằng cách lưu trữ tên của bảng dưới dạng biến người dùng", đó chính là những gì bạn cần.
Bên trong vòng lặp của mình, bạn cần tạo một chuỗi với truy vấn SQL và sử dụng EXECUTE
.
SET @s = CONCAT('select count(distinct signature) from ', tableName);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Theo như tôi hiểu, kết quả của EXECUTE
được gửi đến người gọi của thủ tục được lưu trữ như thể nó là một SELECT
bình thường , vì vậy trong ví dụ này, người gọi sẽ nhận được nhiều bộ kết quả nếu cơ sở dữ liệu của bạn có nhiều hơn một bảng where table_name like "%FAULT_20150320%"
.
Đây là một liên kết đến một câu hỏi SO khác về MySQL dynamic SQL Cách tạo SQL động trong Quy trình lưu trữ MySQL với một số ví dụ.
Có vẻ như bạn muốn một cái gì đó như thế này. Nó phải tổng hợp số lượng từ một số bảng trong signatureCount
biến.
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$$
Một biến thể khác, nếu số lượng bảng bạn cần xử lý không nhiều, là xây dựng động một câu lệnh SQL lớn bao gồm tất cả các bảng bên trong vòng lặp của bạn và sau đó EXECUTE
nó chỉ trong một lần:
SELECT
(COUNT(DISTINCT signature) FROM Table1) +
(COUNT(DISTINCT signature) FROM Table2) +
...
(COUNT(DISTINCT signature) FROM TableN) AS TotalCount