Запланированное выполнение сценария SQL LOAD DATA INFILE в Spring - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь запланировать сценарий LOAD DATA INFILE для периодического обновления таблицы базы данных MySql из файла CSV.

Запланированный метод выполняется, но не сам сценарий.Сценарий выполняется нормально вручную.

Сценарий находится в / resources / sql /

DbConfig.java

@Bean
public DataSource dataSource() {
    DriverManagerDataSource ds = new DriverManagerDataSource();
    ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/my-database");
    ds.setUsername("username");
    ds.setPassword("password");

    // Update DB on startup
    DatabasePopulatorUtils.execute(databasePopulator(), ds);

    return ds;
}

@Bean
public ResourceDatabasePopulator databasePopulator() {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.setSqlScriptEncoding("UTF-8");
    populator.addScript(new ClassPathResource("/sql/ProductUpdate.sql"));
    return populator;
}

// The scheduled method
@Scheduled(fixedDelay = 15000) // Every 15 sec
public void updateProductsTable() {
    DatabasePopulatorUtils.execute(databasePopulator(), this.dataSource());
}

SQL-скрипт

CREATE TEMPORARY TABLE products_temp
(
  product_code varchar(100),
  supplier_number int(10),
  price double,
  product_name varchar(255),
  stock_amount double,
  buying_price double
);


LOAD DATA CONCURRENT LOCAL INFILE 'C:\path\to\csv\product-data.txt' REPLACE 
INTO TABLE products_temp
CHARACTER SET latin1
FIELDS TERMINATED BY ';' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
(product_code, supplier_number, @price, product_name, @stock_amount, 
@buying_price)
SET
  price = replace(@price, ',', '.'),
  stock_amount = replace(@stock_amount, ',', '.'),
  buying_price = replace(@buying_price, ',', '.');

INSERT INTO products (product_code, supplier_number, price, product_name, 
stock_amount, buying_price)
SELECT product_code, supplier_number, price, product_name, stock_amount, 
buying_price FROM products_temp
WHERE product_code NOT IN (SELECT product_code FROM products);

UPDATE products a
JOIN products_temp b ON a.product_code = b.product_code AND 
a.supplier_number = b.supplier_number
SET a.price = b.price,
    a.product_name = b.product_name,
    a.stock_amount = b.stock_amount,
    a.buying_price = b.buying_price;

DROP TABLE products_temp;

Я ожидаю, что скрипт sql выполняется каждые 15 секунд, но на самом деле скрипт вообще не выполняется.

Этот код не выдает ошибок.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Хорошо, удалось исправить это, разделив каждый SQL-запрос в отдельный скрипт.

Решение:

private ResourceDatabasePopulator databasePopulator() {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.addScripts(new ClassPathResource("/sql/products/Create.sql"),
            new ClassPathResource("/sql/products/Load.sql"),
            new ClassPathResource("/sql/products/Insert.sql"),
            new ClassPathResource("/sql/products/Update.sql"),
            new ClassPathResource("/sql/products/Drop.sql"));

    return populator;
}

// The scheduled method
@Scheduled(fixedDelay = 15000) // Every 15 sec
public void updateProductsTable() {
    databasePopulator().execute(dataSource());
}
0 голосов
/ 15 февраля 2019

Я думаю выражение задания cron неверно, попробуйте выполнить с помощью следующего метода планирования, я обновил CRON

 @Bean
 @Scheduled(cron = "0/15 * * * * ?") // Every 15 sec
 public void updateProductsTable() {
 DatabasePopulatorUtils.execute(databasePopulator(), this.dataSource());
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...