休眠-无法创建存储过程

时间:2020-11-02 00:24:27

标签: java mysql hibernate

我最近从使用预填充的数据库切换为允许Hibernate创建我的表。尝试在data.sql中创建存储过程时,出现以下错误:

Exception in thread "task-2" org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #7 of URL [file:/C:/Users/samuel/IdeaProjects/Capripol/target/classes/data.sql]: CREATE PROCEDURE CalculateUserRating( IN baseRating NUMERIC(5,2), IN userID int, IN focusID int, OUT userRating NUMERIC(5,2)) BEGIN SELECT IFNULL(baseRating + SUM(s.sightingValue), baseRating) INTO userRating FROM Sighting s WHERE s.sighteeUserID = userID AND s.sightedFocusID = focusID AND s.sighterUserID != userID; nested exception is java.sql.SQLSyntaxErrorException: 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 '' at line 1

我尝试将?allowMultiQueries=true添加到我的spring.datasource.url中,但这没什么区别。同样,我尝试了this answer,也没什么区别。

data.sql:

DROP PROCEDURE IF EXISTS CalculateUserRating;
CREATE PROCEDURE CalculateUserRating(
    IN baseRating NUMERIC(5,2),
    IN userID int,
    IN focusID int,
    OUT userRating NUMERIC(5,2))
BEGIN
    SELECT IFNULL(baseRating + SUM(s.sightingValue), baseRating)
           INTO userRating
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END;

DROP PROCEDURE IF EXISTS CalculateSightingValue;
CREATE PROCEDURE CalculateSightingValue(
    IN baseRating int,
    IN userID int,
    IN focusID int,
    OUT sightingValue NUMERIC(5,2))
BEGIN
    CALL CalculateUserRating(baseRating, userID, focusID, @userRating);
    SELECT (@userRating/100)
           INTO sightingValue;
END;

#If first sighting it will return 1 as user rating.

DROP PROCEDURE IF EXISTS GetSightingSummary;
CREATE PROCEDURE GetSightingSummary(
    IN userID int,
    IN focusID int,
    OUT totalSightings int,
    OUT selfSightings int,
    OUT peerSightings int,
    OUT otherSightings int)
BEGIN
    SELECT count(*) INTO totalSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID;
    SELECT count(*) INTO selfSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = s.sighterUserID
      AND
            s.sighteeUserID = userID;
    SELECT count(*) INTO peerSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END;

编辑:

我尝试将DELIMITER //添加到脚本的开头和结尾,并尝试在每个单独的过程之间添加定界符,但是没有区别。根据{{​​3}},分隔符不是必需的。

DELIMITER //
DROP PROCEDURE IF EXISTS CalculateUserRating;
DROP PROCEDURE IF EXISTS CalculateSightingValue;
DROP PROCEDURE IF EXISTS GetSightingSummary;
CREATE PROCEDURE CalculateUserRating(
    IN baseRating NUMERIC(5,2),
    IN userID int,
    IN focusID int,
    OUT userRating NUMERIC(5,2))
BEGIN
    SELECT IFNULL(baseRating + SUM(s.sightingValue), baseRating)
           INTO userRating
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END;

CREATE PROCEDURE CalculateSightingValue(
    IN baseRating int,
    IN userID int,
    IN focusID int,
    OUT sightingValue NUMERIC(5,2))
BEGIN
    CALL CalculateUserRating(baseRating, userID, focusID, @userRating);
    SELECT (@userRating/100)
           INTO sightingValue;
END;

#If first sighting it will return 1 as user rating.


CREATE PROCEDURE GetSightingSummary(
    IN userID int,
    IN focusID int,
    OUT totalSightings int,
    OUT selfSightings int,
    OUT peerSightings int,
    OUT otherSightings int)
BEGIN
    SELECT count(*) INTO totalSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID;
    SELECT count(*) INTO selfSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = s.sighterUserID
      AND
            s.sighteeUserID = userID;
    SELECT count(*) INTO peerSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END//
DELIMITER ;

完整错误堆栈跟踪:

Exception in thread "task-2" org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #10 of URL [file:/C:/Users/samuel/IdeaProjects/Capripol/target/classes/data.sql]: CREATE PROCEDURE CalculateUserRating( IN baseRating NUMERIC(5,2), IN userID int, IN focusID int, OUT userRating NUMERIC(5,2)) BEGIN SELECT IFNULL(baseRating + SUM(s.sightingValue), baseRating) INTO userRating FROM Sighting s WHERE s.sighteeUserID = userID AND s.sightedFocusID = focusID AND s.sighterUserID != userID; nested exception is java.sql.SQLSyntaxErrorException: 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 '' at line 1
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:622)
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:254)
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:49)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:202)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.initSchema(DataSourceInitializer.java:119)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.onApplicationEvent(DataSourceInitializerInvoker.java:91)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker.onApplicationEvent(DataSourceInitializerInvoker.java:38)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:99)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.access$100(DataSourceInitializedPublisher.java:50)
    at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher.lambda$postProcessEntityManagerFactory$0(DataSourceInitializedPublisher.java:200)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLSyntaxErrorException: 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 '' at line 1
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:764)
    at com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:648)
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:601)
    ... 17 more

1 个答案:

答案 0 :(得分:0)

MySQL之前和之后都需要DELIMITER,因为它必须确定存储过程或函数在哪里开始和结束。

我也重新排列了一下,因为该命令本来不想运行

USE testdb;
DELIMITER //
DROP PROCEDURE IF EXISTS CalculateUserRating;
DROP PROCEDURE IF EXISTS CalculateSightingValue;
DROP PROCEDURE IF EXISTS GetSightingSummary;
CREATE PROCEDURE CalculateUserRating(
    IN baseRating NUMERIC(5,2),
    IN userID int,
    IN focusID int,
    OUT userRating NUMERIC(5,2))
BEGIN
    SELECT IFNULL(baseRating + SUM(s.sightingValue), baseRating)
           INTO userRating
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END;

CREATE PROCEDURE CalculateSightingValue(
    IN baseRating int,
    IN userID int,
    IN focusID int,
    OUT sightingValue NUMERIC(5,2))
BEGIN
    CALL CalculateUserRating(baseRating, userID, focusID, @userRating);
    SELECT (@userRating/100)
           INTO sightingValue;
END;

#If first sighting it will return 1 as user rating.


CREATE PROCEDURE GetSightingSummary(
    IN userID int,
    IN focusID int,
    OUT totalSightings int,
    OUT selfSightings int,
    OUT peerSightings int,
    OUT otherSightings int)
BEGIN
    SELECT count(*) INTO totalSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID;
    SELECT count(*) INTO selfSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = s.sighterUserID
      AND
            s.sighteeUserID = userID;
    SELECT count(*) INTO peerSightings
    FROM Sighting s
    WHERE
            s.sighteeUserID = userID
      AND
            s.sightedFocusID = focusID
      AND
            s.sighterUserID != userID;

END//
DELIMITER ;
相关问题