2017-03-17 2 views
5

にデータを埋める - ここでtable_nameは、MIN_DATE、MAX_DATEは、私は がフィールドを持つ結果表を取得する必要があるすべてのテーブルに対してクエリを実行し、新しいもの

は、私はすべてのテーブルに対して実行する必要があり、私のクエリ、ある

トン
SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate 
FROM (SELECT short_date, type, value, count(*) as cnt 
FROM testTable 
GROUP BY short_date 
HAVING COUNT(*) > 1) as Duplicates 

は、それから私は、私はこのよう

SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` 
WHERE `TABLES`.`TABLE_SCHEMA` = 'test' 
AND `TABLES`.`TABLE_NAME` LIKE 'test%' 

でそれを行う すべてのテーブル名を取得する方法を発見しかし、私はすべてのためにそれを実行する方法がわかりません新しいテーブルに結果を記入して記入してください。

私は、このように

DECLARE @DB_Name varchar(50) 
DECLARE @Command varchar(100); 
DECLARE database_cursor CURSOR FOR 
SELECT name 
FROM (SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` 
WHERE `TABLES`.`TABLE_SCHEMA` = 'test' 
AND `TABLES`.`TABLE_NAME` LIKE 'test%') as TableNames 

OPEN database_cursor 

FETCH NEXT FROM database_cursor INTO @DB_Name 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @Command = 'SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate 
FROM (SELECT short_date, type, value, count(*) as cnt 
FROM ' + @DB_Name + ' 
WHERE type = ''test'' 
GROUP BY short_date, type, value 
HAVING COUNT(*) > 1) as Duplicates' 
    EXEC sp_executesql @Command 

    FETCH NEXT FROM database_cursor INTO @DB_Name 
END 

CLOSE database_cursor 
DEALLOCATE database_cursor 

それを実行しようとしました。しかし、私はこのエラーに

構文エラーまたはアクセス違反を得た:1064あなたは、あなたのSQL 構文でエラーが発生しています。近くで使用する権利構文についてはMySQLサーバのバージョン に対応して、手動チェックライン1

UPD

で 'DECLAREの@db_nameのVARCHAR(50) @CommandのVARCHAR(100)を宣言'
CREATE PROCEDURE GetData() 
BEGIN 

DECLARE @DB_Name varchar(50), @Command varchar(100); 
DECLARE database_cursor CURSOR FOR 
SELECT name 
FROM (SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` 
WHERE `TABLES`.`TABLE_SCHEMA` = 'test' 
AND `TABLES`.`TABLE_NAME` LIKE 'test%_') as TableNames 

OPEN database_cursor 

FETCH NEXT FROM database_cursor INTO @DB_Name 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @Command = 'SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate 
FROM (SELECT short_date, type, value, count(*) as cnt 
FROM ' + @DB_Name + ' 
WHERE type = ''test'' 
GROUP BY short_date, type, value 
HAVING COUNT(*) > 1) as Duplicates' 
    EXEC sp_executesql @Command 

    FETCH NEXT FROM database_cursor INTO @DB_Name 
END; 

CLOSE database_cursor 
DEALLOCATE database_cursor 

END; 

CALL GetData() 
+0

sql-serverとmysqlの両方にタグを付けました。あなたのエラーメッセージはmysqlを参照するので、sql-serverは間違っていなければなりません。削除してください。 –

+0

ありがとうございます。私はt-sqlを削除するように言わなければなりませんでした。なぜなら、これはSQL-Server(そしてMySQLではなく)上で使用されるSQLの風味です。 –

+0

あなたは正確に何をしようとしているのかの例を挙げることができます – Cherif

答えて

5

最初にDELIMITER $$を追加します。 ENDの後にDELIMITER ;を追加します。

declarationコマンドを削除します。代わりに@commandを使用してください。これは宣言する必要はありません。

SELECT @command := ...;の後にSELECT @command;を追加すると、デバッグができるようになります。

CLOSEおよびDEALLOCATEステートメントは、終了するには;が必要です。

FETCHに行がなくなったことのテスト。

実際には、ストアドプロシージャの多くの例、特にカーソルを持つプロシージャの例を見る必要があります。

更新

うわ、私は半分も構文エラーを発見しませんでした。これは、(私はあなたの特定のテーブルやカラムを持っていないので、私が言うことはできません。)うまくいくかもしれない:

DROP PROCEDURE IF EXISTS so42856538; 

DELIMITER $$ 

CREATE PROCEDURE so42856538() 
    LANGUAGE SQL 
    MODIFIES SQL DATA 
    SQL SECURITY INVOKER 
BEGIN 

DECLARE _TableName varchar(64); 
DECLARE _done INT DEFAULT FALSE; 
DECLARE database_cursor CURSOR FOR 
    SELECT TABLE_NAME 
     FROM `information_schema`.`TABLES` 
     WHERE `TABLE_SCHEMA` = 'test' 
      AND `TABLE_NAME` LIKE 'test%'; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE; 

OPEN database_cursor; 
curs_loop: LOOP 
    FETCH NEXT FROM database_cursor INTO _TableName; 
    IF _done THEN LEAVE curs_loop; END IF; 
    SET @Command := CONCAT(
      'SELECT MIN(short_date) as FirstDuplicatedDate, 
          MAX(short_date) as LastDuplicatedDate 
      FROM (SELECT short_date, type, value, count(*) as cnt 
        FROM ', _TableName, ' 
        WHERE type = "test" 
        GROUP BY short_date, type, value 
        HAVING COUNT(*) > 1) as Duplicates' 
         ); 
    SELECT _TableName, @command; -- Debugging (remove if it is clutter) 
    PREPARE _sql FROM @command; 
    EXECUTE _sql; 
    DEALLOCATE PREPARE _sql; 
END LOOP; 
CLOSE database_cursor; 

END $$ 

DELIMITER ; 

CALL so42856538; 
+0

'更新'に構文エラー(私にとって)はありません。 –

+0

SQLSTATE [42000]:構文エラーまたはアクセス違反:1064 SQL構文にエラーがあります。あなたのMySQLサーバーのバージョンに対応するマニュアルをチェックして、正しい構文が使用できるようにしてください。 'DELIMITER $$ – Ekaterina

+0

どのバージョンのMySQL? 'DELIMITER'と' $$'の間にスペースがありましたか?これをMySQLサーバに送信するためにどのようなクライアントを使用していますか? (私はmysqlコマンドラインツールを使用していました) –

-2

限り、このエラーは、DELIMETERと1あなたが持っているより多くの事が原因である私の知識の懸念として適切にカーソルを適用するために、私はCURSOR .Makeダイナミッククエリでprocedureを書いていた以下のコードで全体rowset .Hereを反復処理し、動的なクエリが戻って正確な出力したいということ

PREPARE stmt FROM @VAR_QRY; EXECUTE stmt; 

使用して、そのダイナミックなクエリを実行します。ここで私はあなたがtriggerに関する基本的な知識を持っていることを想定していた、loopCursor

はコードの下に試してみてください。 これが役立つことを願っています。

DROP PROCEDURE IF EXISTS ITERATEALLTABLE; 
DELIMITER $$ 
CREATE PROCEDURE ITERATEALLTABLE() 
BEGIN 
DECLARE VAR_TABLE varchar(100); 
DECLARE VAR_QRY varchar(100); 
DECLARE VAR_FINISHED INT(11) DEFAULT 0; 
DECLARE DATABASE_CURSOR CURSOR FOR 
       SELECT name AS TableNames 
       FROM (
        SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` 
        WHERE `TABLES`.`TABLE_SCHEMA` = 'test' 
        AND `TABLES`.`TABLE_NAME` LIKE 'test%' 
       )Z ; 


       DECLARE CONTINUE HANDLER FOR NOT FOUND SET VAR_FINISHED = 1; 

       OPEN DATABASE_CURSOR; 
       GET_NEXTRECORD: LOOP 

         FETCH DATABASE_CURSOR INTO VAR_TABLE; 

          IF VAR_FINISHED = 1 THEN 
          LEAVE GET_NEXTRECORD; 
          END IF; 

          SET @VAR_QRY = CONCAT("SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate 
          FROM (SELECT short_date, type, value, count(*) as cnt 
          FROM " , VAR_TABLE , " WHERE type = 'test' 
          GROUP BY short_date, type, value 
          HAVING COUNT(*) > 1) as Duplicates"); 

          PREPARE stmt FROM @VAR_QRY; 
          EXECUTE stmt; 

       END LOOP GET_NEXTRECORD; 

       CLOSE DATABASE_CURSOR; 

END; 

CALL ITERATEALLTABLE; 
+0

'DECLARE'の' VAR_QRY'は '@ VAR_QRY'とまったく異なります。 –

1

右...これを試してみるとよいでしょう。

この行を削除し、再度クエリを実行します。

DECLARE @DB_Name varchar(50), @Command varchar(100); 

mysqlでは、宣言せずに必要なときに変数を使うことができます。

関連する問題