Как создать хранимую процедуру в MySQL с помощью Knex raw - PullRequest
0 голосов
/ 22 июня 2019

Я использую Adonis, который использует Knex под капотом. Я хочу создать эту хранимую процедуру


DROP PROCEDURE IF EXISTS fill_date_dimension;
DELIMITER //
CREATE PROCEDURE fill_date_dimension(IN startdate DATE,IN stopdate DATE)
BEGIN
    DECLARE currentdate DATE;
    SET currentdate = startdate;
    WHILE currentdate < stopdate DO
        INSERT INTO time_dimension VALUES (
                        YEAR(currentdate)*10000+MONTH(currentdate)*100 + DAY(currentdate),
                        currentdate,
                        YEAR(currentdate),
                        MONTH(currentdate),
                        DAY(currentdate),
                        QUARTER(currentdate),
                        WEEKOFYEAR(currentdate),
                        DATE_FORMAT(currentdate,'%W'),
                        DATE_FORMAT(currentdate,'%M'),
                        'f',
                        CASE DAYOFWEEK(currentdate) WHEN 1 THEN 't' WHEN 7 then 't' ELSE 'f' END,
                        NULL);
        SET currentdate = ADDDATE(currentdate,INTERVAL 1 DAY);
    END WHILE;
END
//
DELIMITER ;

TRUNCATE TABLE time_dimension;

CALL fill_date_dimension('2018-01-01','2030-12-31');
OPTIMIZE TABLE time_dimension;

Проблема в том, что knex raw или, может быть, Adonis (я не знаю) удаляет разрывы строк. Это дает мне ошибку

DROP PROCEDURE IF EXISTS fill_date_dimension; DELIMITER // CREATE PROCEDURE fill_date_dimension(IN startdate DATE,IN stopdate DATE) BEGIN DECLARE currentdate DATE; SET currentdate = startdate; WHILE currentdate < stopdate DO INSERT INTO dates VALUES ( YEAR(currentdate)*10000+MONTH(currentdate)*100 + DAY(currentdate), currentdate, YEAR(currentdate), MONTH(currentdate), DAY(currentdate), QUARTER(currentdate), WEEKOFYEAR(currentdate), DATE_FORMAT(currentdate,'%W'), DATE_FORMAT(currentdate,'%M'), 'f', CASE DAYOFWEEK(currentdate) WHEN 1 THEN 't' WHEN 7 then 't' ELSE 'f' END, NULL); SET currentdate = ADDDATE(currentdate,INTERVAL 1 DAY); END WHILE; END // DELIMITER ; TRUNCATE TABLE dates; CALL fill_date_dimension('2018-01-01','2030-12-31'); OPTIMIZE TABLE time_dimension; - ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER // CREATE PROCEDURE fill_date_dimension(IN startdate DATE,IN sto' at line 4

Я пытался вставить свои собственные \n теги в SQL, но они были удалены.

Любая идея, чтобы заставить knex.raw выполнять то, что я даю, вместо того, чтобы убирать теги.

1 Ответ

0 голосов
/ 22 июня 2019

Таким образом, выясняется, что проблема связана не с клиентом, а с ядром базы данных, которое не может принимать несколько команд в одной строке.

В конце концов, я нашел другой способ сделать то же самое без использования процедуры, но мне пришлось выполнять каждую строку кода как отдельную команду, как это.

await db.raw(`DROP TABLE IF EXISTS numbers_small;`)
    await db.raw(`DROP TABLE IF EXISTS numbers_small;`)
    await db.raw(`CREATE TABLE numbers_small (number INT);`)
    await db.raw(`INSERT INTO numbers_small VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);`)
    await db.raw(`DROP TABLE IF EXISTS numbers;`)
    await db.raw(`CREATE TABLE numbers (number BIGINT);`)
    await db.raw(`INSERT INTO numbers
    SELECT thousands.number * 1000 + hundreds.number * 100 + tens.number * 10 + ones.number
      FROM numbers_small thousands, numbers_small hundreds, numbers_small tens, numbers_small ones
    LIMIT 1000000;`)
    await db.raw(`DROP TABLE IF EXISTS dates;`)
    await db.raw(`CREATE TABLE dates (
      date_id          BIGINT PRIMARY KEY, 
      date             DATE NOT NULL,
      timestamp        BIGINT, 
      weekend          CHAR(10) NOT NULL DEFAULT "Weekday",
      day_of_week      CHAR(10),
      month            CHAR(10),
      month_day        INT, 
      year             INT,
      week_starting_monday CHAR(2),
      UNIQUE KEY date (date),
      KEY year_week (year,week_starting_monday)
    );`)
    await db.raw(`INSERT INTO dates (date_id, date)
    SELECT number, DATE_ADD( '2016-01-01', INTERVAL number DAY )
      FROM numbers
      WHERE DATE_ADD( '2016-01-01', INTERVAL number DAY ) BETWEEN '2016-01-01' AND '2030-01-01'
      ORDER BY number;`)
    await db.raw(`UPDATE dates SET
    timestamp =   UNIX_TIMESTAMP(date),
    day_of_week = DATE_FORMAT( date, "%W" ),
    weekend =     IF( DATE_FORMAT( date, "%W" ) IN ('Saturday','Sunday'), 'Weekend', 'Weekday'),
    month =       DATE_FORMAT( date, "%M"),
    year =        DATE_FORMAT( date, "%Y" ),
    month_day =   DATE_FORMAT( date, "%d" );`)
    await db.raw(`UPDATE dates SET week_starting_monday = DATE_FORMAT(date,'%v');`)
...