1

スタック取引所の仲間の住人、

現在、非常に大きな方法でデータを再フォーマットする手順を作成しようとしています。チケットに関するデータのリストを取得します (ランダムな月の要約)。入力ビューには常に同じ列がありますが、月を列として表示する必要があるためです (通常、ビューの Monat 列に値として入力されます)。すっごく、いくつかの主要な調査、試行錯誤、そして多くの頭痛の種の後、私はそれを機能させるようになりました. この手順は、単一のチケット番号を受け入れ、その単一のチケットのすべての統計を「返します」。

私はこれを行います:

  1. 月ごとに繰り返し、CREATE TEMPORARY TABLE ステートメントを作成します。
  2. そのステートメントを実行してから、ステートメントの割り当てを解除します
  3. 各チケット値を反復処理し、INSERT INTO ON DUPLICATE KEY UPDATE ステートメントを使用してそれらを一時テーブルに並べ替えます (各反復を新たに構築、実行、および割り当て解除します)。
  4. 繰り返しますが、月ごとに反復し、最後の更新を作成して要約列を埋めます (もちろん、これをステップ 1 に結合することもできますが、読みやすくするために、ステップをできる限り分けようとしました。完了したら最適化して、必要に応じて機能させることができます)。
  5. 一時テーブルを選択して、それが返されるようにします
  6. 私は習慣的にきちんとした人なので、未解決の問題を片付けてください。

良い点: それは動作します! 悪い点: 1 つの入力値に対してのみ機能します。別のチケット番号に変更すると、列に別の月が必要になり、「エラーコード1054、フィールドリストの不明な列」で失敗し、現在のクエリにあるはずのない古い列 (月) を参照します。一時テーブルの列が同一である限り、プロシージャは何度でも実行できます。この動作は、プロシージャを削除して再作成するか、新しい接続を作成するたびにリセットされます。

明らかに、私は途中でクリーニングのステップを実行するのを忘れています.SQL全般にかなり慣れていないため、特にMySQLはおそらくそれを探すことさえ知らなかったでしょう:(.

助けていただければ幸いです、ありがとう、フレッド

DELIMITER //
CREATE PROCEDURE proc_get_relevant_tickets(bID VARCHAR(10))
DETERMINISTIC
READS SQL DATA
BEGIN
# Declare storage vairables for withdrawing data from view
DECLARE ID, FiID, ZVB, ZNVB, ZGes, WVB, WNVB, WGes INTEGER;
DECLARE Mon VARCHAR(50);
DECLARE RowVerb, RowNVerb, RowGes, Counter INTEGER;
DECLARE verbucht, nichtverbucht, gesamt VARCHAR(50);
DECLARE currentticket INTEGER;
DECLARE statezges, statewges LONGTEXT;

# Declare runtime stuff
DECLARE done INT DEFAULT FALSE;
DECLARE declaration LONGTEXT;
DECLARE temptext VARCHAR(50);
DECLARE Months CURSOR FOR SELECT DISTINCT Monat FROM view_list_of_tickets t WHERE bID = t.ID;
DECLARE `Values` CURSOR FOR SELECT * FROM view_list_of_tickets t WHERE bID = t.ID;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

# Clean up in case something interrupted last execution
DROP TEMPORARY TABLE IF EXISTS temp_storage_5437485;

# If there are any entries to work upon
IF (SELECT COUNT(t.ID) FROM view_list_of_tickets t WHERE bID = t.ID > 0)
THEN
    # Create temporary table to put the values into
    SET declaration = 'CREATE TEMPORARY TABLE `temp_storage_5437485` (ID INTEGER PRIMARY KEY, TicketNr INTEGER, Category VARCHAR(50), ';

    SET done = FALSE;
    OPEN Months;
    read_loop: LOOP
        FETCH Months INTO temptext;
        IF done THEN
            LEAVE read_loop;
        END IF;
        SET declaration = CONCAT(declaration, '`', temptext, ' Zeit` INTEGER DEFAULT 0, ');
        SET declaration = CONCAT(declaration, '`', temptext, ' Wert` INTEGER DEFAULT 0, ');
    END LOOP;
    CLOSE Months;

    SET declaration = CONCAT(declaration, '`Gesamt Zeit` INTEGER, `Gesamt Wert` INTEGER);');
    SELECT declaration INTO @declaration;
    PREPARE stmt FROM @declaration;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    # End of creating the storage container

    # Cycle through values and input into temporary table
    SET done = FALSE;
    SET verbucht = 'Verbucht';
    SET nichtverbucht = 'Nicht Verbucht';
    SET gesamt = 'Gesamt';
    SET currentticket = 0;
    SET Counter = 0;
    SET RowVerb = 1;
    SET RowNVerb = 2;
    SET RowGes = 3;
    OPEN `Values`;
    read_values: LOOP
        FETCH `Values` INTO ID, FiID, ZVB, ZNVB, ZGes, WVB, WNVB, WGes, Mon;
        IF done THEN
            LEAVE read_values;
        END IF;

        # If a new ticket has been arrived at, increment the counters
        IF currentticket > 0 AND ID <> currentticket THEN
            SET currentticket = ID;
            SET Counter = Counter + 1;
            SET RowVerb = RowVerb + 3;
            SET RowNVerb = RowNVerb + 3;
            SET RowGes = RowGes + 3;
        END IF;

        IF currentticket = 0 AND ID <> currentticket THEN
            SET currentticket = ID;
        END IF;

        # Insert first (Verbucht) row
        SET declaration = CONCAT('INSERT INTO `temp_storage_5437485` (`ID`, `TicketNr`, `', Mon, ' Zeit`, `', Mon, ' Wert`) VALUES (');
        SET declaration = CONCAT(declaration, RowVerb, ', ', ID, ', ', ZVB, ', ', WVB, ') ON DUPLICATE KEY UPDATE ');
        SET declaration = CONCAT(declaration, '`', Mon, ' Zeit`=', ZVB, ', `', Mon, ' Wert`=', WVB, ';');
        SELECT declaration INTO @declaration;
        PREPARE stmt FROM @declaration;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        # Insert second (Nicht Verbucht) row
        SET declaration = CONCAT('INSERT INTO `temp_storage_5437485` (`ID`, `TicketNr`, `', Mon, ' Zeit`, `', Mon, ' Wert`) VALUES (');
        SET declaration = CONCAT(declaration, RowNVerb, ', ', ID, ', ', ZNVB, ', ', WNVB, ') ON DUPLICATE KEY UPDATE ');
        SET declaration = CONCAT(declaration, '`', Mon, ' Zeit`=', ZNVB, ', `', Mon, ' Wert`=', WNVB, ';');
        SELECT declaration INTO @declaration;
        PREPARE stmt FROM @declaration;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        # Insert third (Gesamt) row
        SET declaration = CONCAT('INSERT INTO `temp_storage_5437485` (`ID`, `TicketNr`, `', Mon, ' Zeit`, `', Mon, ' Wert`) VALUES (');
        SET declaration = CONCAT(declaration, RowGes, ', ', ID, ', ', ZGes, ', ', WGes, ') ON DUPLICATE KEY UPDATE ');
        SET declaration = CONCAT(declaration, '`', Mon, ' Zeit`=', ZGes, ', `', Mon, ' Wert`=', WGes, ';');
        SELECT declaration INTO @declaration;
        PREPARE stmt FROM @declaration;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        UPDATE temp_storage_5437485 SET Category = verbucht WHERE temp_storage_5437485.ID = RowVerb LIMIT 5;
        UPDATE temp_storage_5437485 SET Category = nichtverbucht WHERE temp_storage_5437485.ID = RowNVerb LIMIT 5;
        UPDATE temp_storage_5437485 SET Category = gesamt WHERE temp_storage_5437485.ID = RowGes LIMIT 5;
    END LOOP;
    CLOSE `Values`;
    # End of cycling for values input

    # Being calculating the total values
    SET declaration = 'UPDATE temp_storage_5437485 SET `Gesamt Zeit` = (';
    SET statezges = '';
    SET statewges = '';

    SET done = FALSE;
    OPEN Months;
    read_loop: LOOP
        FETCH Months INTO temptext;
        IF done THEN
            LEAVE read_loop;
        END IF;

        # If not the first entry, add more
        IF statezges <> '' THEN
            SET statezges = CONCAT(statezges, ' + ');
        END IF;
        IF statewges <> '' THEN
            SET statewges = CONCAT(statewges, ' + ');
        END IF;

        # Add column name
        SET statezges = CONCAT(statezges, 'temp_storage_5437485.`', temptext, ' Zeit`');
        SET statewges = CONCAT(statewges, 'temp_storage_5437485.`', temptext, ' Wert`');
    END LOOP;
    CLOSE Months;

    SET declaration = CONCAT(declaration, statezges, '), `Gesamt Wert` = (', statewges, ') LIMIT 100000');
    SELECT declaration INTO @declaration;
    PREPARE stmt FROM @declaration;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    # End calculating the total values

    SELECT * FROM temp_storage_5437485;
    DROP TEMPORARY TABLE IF EXISTS temp_storage_5437485;
ELSE
    SELECT 'is null';
END IF;

DROP TEMPORARY TABLE IF EXISTS temp_storage_5437485;
END //

DELIMITER ;
4

0 に答える 0