一、场景
我需要在启动springboot应用的同时,在数据库中创建表和初始一些数据。
二、用法
其实实现这个需求有多种方式(这里我不多啰嗦,各位可以自行百度),我采用的是spring.sql.init.schema-locations配置创建数据库和主键索引的SQL语句,使用spring.sql.init.data-locations初始化表数据,使用简单明了。
spring.sql.init.schema-locations=classpath:sql/xxxx.sql
spring.sql.init.data-locations=classpath:sql/xxxx.sql
CREATE TABLE IF NOT EXISTS "t_counter" (
"id" varchar(36) COLLATE "pg_catalog"."default" NOT NULL,
"count" int4,
"url" varchar(255) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "t_counter"."count" IS '点击次数';
COMMENT ON COLUMN "t_counter"."url" IS '官网地址';
COMMENT ON TABLE "t_counter" IS '官网点击次数';
CREATE TABLE IF NOT EXISTS "t_reservation" (
"id" varchar(36) COLLATE "pg_catalog"."default" NOT NULL,
"corporate_name" varchar(200) COLLATE "pg_catalog"."default",
"create_date" timestamp(6),
"name" varchar(50) COLLATE "pg_catalog"."default",
"phone_num" varchar(11) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "t_reservation"."corporate_name" IS '公司名称';
COMMENT ON COLUMN "t_reservation"."create_date" IS '创建时间';
COMMENT ON COLUMN "t_reservation"."name" IS '姓名';
COMMENT ON COLUMN "t_reservation"."phone_num" IS '电话';
COMMENT ON TABLE "t_reservation" IS '预约信息';
-- ----------------------------
-- Primary Key structure for table t_counter
-- ----------------------------
DO
$$
BEGIN
IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = 't_counter' AND constraint_name = 't_counter_pkey') THEN
ALTER TABLE t_counter ADD CONSTRAINT t_counter_pkey PRIMARY KEY ("id");
END IF;
END;
$$;
-- ----------------------------
-- Primary Key structure for table t_reservation
-- ----------------------------
DO
$$
BEGIN
IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = 't_reservation' AND constraint_name = 't_reservation_pkey') THEN
ALTER TABLE t_reservation ADD CONSTRAINT t_reservation_pkey PRIMARY KEY ("id");
END IF;
END;
$$;
是不是看着什么问题也没有,是不是很简单,我当时也是这么认为,而且我在navicat中执行也没有任何问题。
三、问题
结果天不如人愿,往往你认为越简单的东西,越会给你一些意想不到的结果。这不报错就来了吧!
Caused by: org.postgresql.util.PSQLException: Unterminated dollar quote started at position 3 in SQL DO $$ BEGIN IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = ''t_counter'' AND constraint_name = ''t_counter_pkey'') THEN ALTER TABLE t_counter ADD CONSTRAINT t_counter_pkey PRIMARY KEY ("id"). Expected terminating $$
at org.postgresql.core.Parser.checkParsePosition(Parser.java:1443) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.core.Parser.parseSql(Parser.java:1342) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.core.Parser.replaceProcessing(Parser.java:1294) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.core.CachedQueryCreateAction.create(CachedQueryCreateAction.java:43) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.core.QueryExecutorBase.createQueryByKey(QueryExecutorBase.java:369) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:313) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:297) ~[postgresql-42.6.2.jar:42.6.2]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:292) ~[postgresql-42.6.2.jar:42.6.2]
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:94) ~[HikariCP-5.0.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-5.0.1.jar:na]
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:261) ~[spring-jdbc-6.1.8.jar:6.1.8]
... 27 common frames omitted
看到这个问题,首先感觉就是,这都会报错?
赶紧翻译一下:未终止的 $ 符号从sql语句中的第3位开始。预期终止 $。
说人话就是,没有以$$ 结束语句??
赶紧分析一下,我语句没有问题,navicat可以执行,那只能是spring在解析sql语句后执行出错了。可能解析的语句不是pgsql的语法。
四、如何解决
在网上找了找问题解决办法,搜索Unterminated dollar quote started at position 3 in SQL,居然第一篇文章就是解决这个问题的,
万能的stack overflow。。
For platforms that don't recognize dollar quoting you can use ' instead. You'll need to escape any ' in the body of the anonymous function though.
意思是:对于不认可$$符号的平台,您可以使用 ‘’ 代替。不过,您需要转义匿名函数主体中的任何单引号改为两个单引号’‘’'。
按照上述说明修改我自己的sql语句:
-- ----------------------------
-- Primary Key structure for table t_counter
-- ----------------------------
DO
'
BEGIN
IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = ''t_counter'' AND constraint_name = ''t_counter_pkey'') THEN
ALTER TABLE t_counter ADD CONSTRAINT t_counter_pkey PRIMARY KEY ("id");
END IF;
END;
';
-- ----------------------------
-- Primary Key structure for table t_reservation
-- ----------------------------
DO
'
BEGIN
IF NOT EXISTS (SELECT constraint_name FROM information_schema.table_constraints WHERE table_name = ''t_reservation'' AND constraint_name = ''t_reservation_pkey'') THEN
ALTER TABLE t_reservation ADD CONSTRAINT t_reservation_pkey PRIMARY KEY ("id");
END IF;
END;
';
完美运行!!!!!搞定!!!
在此记录一下,避免忘记。。。愿工作中没有BUG!!!!