338 lines
16 KiB
PL/PgSQL
338 lines
16 KiB
PL/PgSQL
-- ==============================================================================
|
|
-- RailwaySystem 数据库 V2 回滚脚本: 002_rollback_modified_tables.sql
|
|
-- 适用数据库: KingbaseES V009R003C018 (schema: public)
|
|
-- 执行目标: 严格基于 000_phase05_exact_schema.sql 结构与 bak_v1_* 数据还原 13 张表
|
|
-- 事务边界: 全程在显式事务 BEGIN ... COMMIT 中执行
|
|
-- 规范要求:
|
|
-- 1. 彻底摒弃 CTAS 丢失约束/默认值/触发器的不可靠方案
|
|
-- 2. 精确采用 Phase 0.5 原始 DDL 重建表结构
|
|
-- 3. 从 bak_v1_* 恢复真实数据并严格校验行数
|
|
-- ==============================================================================
|
|
|
|
BEGIN;
|
|
|
|
-- 步骤 1: 显式解除既有 V2 外键约束与旧外键
|
|
ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS uq_dorm_auth_accomm;
|
|
ALTER TABLE train_dorm_auth DROP CONSTRAINT IF EXISTS fk_dormauth_accomm;
|
|
ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS uq_class_report_enroll;
|
|
ALTER TABLE train_class_report DROP CONSTRAINT IF EXISTS fk_report_enrollment;
|
|
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS uq_student_checkin_enroll_lesson;
|
|
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_enrollment;
|
|
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_lesson;
|
|
ALTER TABLE train_student_checkin DROP CONSTRAINT IF EXISTS fk_checkin_board;
|
|
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_enrollment;
|
|
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_plancourse;
|
|
ALTER TABLE train_study_duration DROP CONSTRAINT IF EXISTS fk_study_resource;
|
|
ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS uq_student_portrait_enroll;
|
|
ALTER TABLE train_student_portrait DROP CONSTRAINT IF EXISTS fk_portrait_enrollment;
|
|
ALTER TABLE train_electronic_board DROP CONSTRAINT IF EXISTS fk_board_classroom;
|
|
|
|
-- 步骤 2: 常规 DROP 13 张表
|
|
DROP TABLE IF EXISTS train_student_portrait;
|
|
DROP TABLE IF EXISTS train_study_duration;
|
|
DROP TABLE IF EXISTS train_student_checkin;
|
|
DROP TABLE IF EXISTS train_class_report;
|
|
DROP TABLE IF EXISTS train_dorm_auth;
|
|
DROP TABLE IF EXISTS train_electronic_board;
|
|
DROP TABLE IF EXISTS train_dormitory_info;
|
|
DROP TABLE IF EXISTS train_class_plan;
|
|
DROP TABLE IF EXISTS train_training_site;
|
|
DROP TABLE IF EXISTS train_classroom_info;
|
|
DROP TABLE IF EXISTS train_course;
|
|
DROP TABLE IF EXISTS train_student;
|
|
DROP TABLE IF EXISTS train_teacher;
|
|
|
|
-- 步骤 3: 严格依据 Phase 0.5 原始 DDL 重建 13 张表物理结构
|
|
|
|
CREATE TABLE train_teacher (
|
|
t_id VARCHAR(32) NOT NULL,
|
|
t_name VARCHAR(30) NOT NULL,
|
|
t_gender CHAR(2),
|
|
t_birth DATE,
|
|
t_department VARCHAR(50) NOT NULL,
|
|
t_title VARCHAR(30),
|
|
t_phone VARCHAR(20),
|
|
t_email VARCHAR(50),
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_teacher PRIMARY KEY (t_id)
|
|
);
|
|
|
|
CREATE TABLE train_student (
|
|
s_id VARCHAR(32) NOT NULL,
|
|
s_name VARCHAR(30) NOT NULL,
|
|
s_gender CHAR(2),
|
|
s_birth DATE,
|
|
s_department VARCHAR(50) NOT NULL,
|
|
s_major VARCHAR(50) NOT NULL,
|
|
s_class VARCHAR(30),
|
|
s_phone VARCHAR(20),
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_student PRIMARY KEY (s_id)
|
|
);
|
|
|
|
CREATE TABLE train_course (
|
|
c_id VARCHAR(32) NOT NULL,
|
|
c_name VARCHAR(100) NOT NULL,
|
|
c_type VARCHAR(30),
|
|
c_duration INTEGER,
|
|
teaching_objective TEXT,
|
|
course_content TEXT,
|
|
attach_doc TEXT,
|
|
attach_video TEXT,
|
|
attach_model_link TEXT,
|
|
model_resource_ids TEXT,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_course PRIMARY KEY (c_id)
|
|
);
|
|
|
|
CREATE TABLE train_classroom_info (
|
|
class_room_id VARCHAR(32) NOT NULL,
|
|
room_name VARCHAR(60) NOT NULL,
|
|
room_location VARCHAR(100),
|
|
capacity INTEGER,
|
|
room_status SMALLINT DEFAULT 1,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_classroom_info PRIMARY KEY (class_room_id)
|
|
);
|
|
|
|
CREATE TABLE train_training_site (
|
|
site_id VARCHAR(32) NOT NULL,
|
|
site_name VARCHAR(80) NOT NULL,
|
|
site_location VARCHAR(100),
|
|
capacity INTEGER,
|
|
site_device TEXT,
|
|
site_status SMALLINT DEFAULT 1,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_training_site PRIMARY KEY (site_id)
|
|
);
|
|
|
|
CREATE TABLE train_class_plan (
|
|
plan_id VARCHAR(32) NOT NULL,
|
|
plan_name VARCHAR(100) NOT NULL,
|
|
c_id VARCHAR(32) NOT NULL,
|
|
start_time TIMESTAMP NOT NULL,
|
|
end_time TIMESTAMP NOT NULL,
|
|
train_address VARCHAR(100),
|
|
t_id VARCHAR(32) NOT NULL,
|
|
recruit_num INTEGER,
|
|
apply_condition TEXT,
|
|
plan_status SMALLINT DEFAULT 0,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_class_plan PRIMARY KEY (plan_id),
|
|
CONSTRAINT fk_classplan_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_classplan_teacher FOREIGN KEY (t_id) REFERENCES train_teacher (t_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_dormitory_info (
|
|
dorm_id VARCHAR(32) NOT NULL,
|
|
dorm_building VARCHAR(50),
|
|
dorm_room VARCHAR(30) NOT NULL,
|
|
bed_total INTEGER,
|
|
bed_used INTEGER DEFAULT 0,
|
|
lock_device_sn VARCHAR(64),
|
|
dorm_status SMALLINT DEFAULT 1,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_dormitory_info PRIMARY KEY (dorm_id),
|
|
CONSTRAINT uq_dorm_building_room UNIQUE (dorm_building, dorm_room)
|
|
);
|
|
|
|
CREATE TABLE train_electronic_board (
|
|
board_id VARCHAR(32) NOT NULL,
|
|
board_sn VARCHAR(64) NOT NULL,
|
|
bind_classroom_id VARCHAR(32),
|
|
bind_plan_id VARCHAR(32),
|
|
board_ip VARCHAR(50),
|
|
board_content VARCHAR(500),
|
|
board_playmode SMALLINT DEFAULT 1,
|
|
support_checkin_type VARCHAR(30),
|
|
board_status SMALLINT DEFAULT 1,
|
|
last_heartbeat TIMESTAMP,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_electronic_board PRIMARY KEY (board_id),
|
|
CONSTRAINT uq_board_sn UNIQUE (board_sn),
|
|
CONSTRAINT fk_board_classroom FOREIGN KEY (bind_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_board_plan FOREIGN KEY (bind_plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_dorm_auth (
|
|
auth_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
|
student_id VARCHAR(32) NOT NULL,
|
|
plan_id VARCHAR(32) NOT NULL,
|
|
dorm_id VARCHAR(32) NOT NULL,
|
|
bed_no VARCHAR(20),
|
|
face_sync_status SMALLINT DEFAULT 0,
|
|
auth_start TIMESTAMP,
|
|
auth_end TIMESTAMP,
|
|
create_user VARCHAR(32) NOT NULL,
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
remark VARCHAR(200),
|
|
CONSTRAINT pk_train_dorm_auth PRIMARY KEY (auth_id),
|
|
CONSTRAINT uq_dormauth_stu_plan UNIQUE (student_id, plan_id),
|
|
CONSTRAINT fk_dormauth_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_dormauth_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_dormauth_dorm FOREIGN KEY (dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_class_report (
|
|
report_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
|
plan_id VARCHAR(32) NOT NULL,
|
|
student_id VARCHAR(32) NOT NULL,
|
|
report_way SMALLINT,
|
|
report_device_sn VARCHAR(64),
|
|
report_time TIMESTAMP,
|
|
report_status SMALLINT DEFAULT 0,
|
|
alloc_dorm_id VARCHAR(32),
|
|
alloc_classroom_id VARCHAR(32),
|
|
alloc_site_id VARCHAR(32),
|
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT pk_train_class_report PRIMARY KEY (report_id),
|
|
CONSTRAINT uq_classreport_plan_stu UNIQUE (plan_id, student_id),
|
|
CONSTRAINT fk_classreport_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_classreport_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_classreport_dorm FOREIGN KEY (alloc_dorm_id) REFERENCES train_dormitory_info (dorm_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_classreport_classroom FOREIGN KEY (alloc_classroom_id) REFERENCES train_classroom_info (class_room_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_classreport_site FOREIGN KEY (alloc_site_id) REFERENCES train_training_site (site_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_student_checkin (
|
|
checkin_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
|
plan_id VARCHAR(32) NOT NULL,
|
|
c_id VARCHAR(32) NOT NULL,
|
|
student_id VARCHAR(32) NOT NULL,
|
|
board_id VARCHAR(32),
|
|
checkin_way SMALLINT,
|
|
checkin_time TIMESTAMP,
|
|
checkin_status SMALLINT,
|
|
lesson_start_time TIMESTAMP,
|
|
lesson_end_time TIMESTAMP,
|
|
CONSTRAINT pk_train_student_checkin PRIMARY KEY (checkin_id),
|
|
CONSTRAINT uq_checkin_lesson_stu UNIQUE (plan_id, c_id, student_id, lesson_start_time),
|
|
CONSTRAINT fk_checkin_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_checkin_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_checkin_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_checkin_board FOREIGN KEY (board_id) REFERENCES train_electronic_board (board_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_study_duration (
|
|
dur_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
|
student_id VARCHAR(32),
|
|
plan_id VARCHAR(32),
|
|
c_id VARCHAR(32),
|
|
device_type VARCHAR(50),
|
|
start_time TIMESTAMP,
|
|
end_time TIMESTAMP,
|
|
study_seconds INTEGER,
|
|
sync_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT pk_train_study_duration PRIMARY KEY (dur_id),
|
|
CONSTRAINT fk_studydur_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_studydur_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_studydur_course FOREIGN KEY (c_id) REFERENCES train_course (c_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
CREATE TABLE train_student_portrait (
|
|
portrait_id BIGINT GENERATED BY DEFAULT AS IDENTITY,
|
|
student_id VARCHAR(32) NOT NULL,
|
|
plan_id VARCHAR(32) NOT NULL,
|
|
total_study_hour NUMERIC(8,2),
|
|
avg_score NUMERIC(5,2),
|
|
checkin_rate NUMERIC(5,2),
|
|
label_tag TEXT,
|
|
portrait_content TEXT,
|
|
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT pk_train_student_portrait PRIMARY KEY (portrait_id),
|
|
CONSTRAINT uq_portrait_stu_plan UNIQUE (student_id, plan_id),
|
|
CONSTRAINT fk_portrait_stu FOREIGN KEY (student_id) REFERENCES train_student (s_id) ON DELETE NO ACTION,
|
|
CONSTRAINT fk_portrait_plan FOREIGN KEY (plan_id) REFERENCES train_class_plan (plan_id) ON DELETE NO ACTION
|
|
);
|
|
|
|
-- 步骤 4: 重建 9 个历史触发器
|
|
CREATE OR REPLACE TRIGGER trig_train_teacher_modify
|
|
BEFORE UPDATE ON train_teacher
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_student_modify
|
|
BEFORE UPDATE ON train_student
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_course_modify
|
|
BEFORE UPDATE ON train_course
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_classroom_modify
|
|
BEFORE UPDATE ON train_classroom_info
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_trainsite_modify
|
|
BEFORE UPDATE ON train_training_site
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_board_modify
|
|
BEFORE UPDATE ON train_electronic_board
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_dorminfo_modify
|
|
BEFORE UPDATE ON train_dormitory_info
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_classplan_modify
|
|
BEFORE UPDATE ON train_class_plan
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
CREATE OR REPLACE TRIGGER trig_train_dormauth_modify
|
|
BEFORE UPDATE ON train_dorm_auth
|
|
FOR EACH ROW EXECUTE FUNCTION func_train_update_modifytime();
|
|
|
|
-- 步骤 5: 从 bak_v1_* 物理快照还原数据
|
|
INSERT INTO train_teacher SELECT * FROM bak_v1_train_teacher;
|
|
INSERT INTO train_student SELECT * FROM bak_v1_train_student;
|
|
INSERT INTO train_course SELECT * FROM bak_v1_train_course;
|
|
INSERT INTO train_classroom_info SELECT * FROM bak_v1_train_classroom_info;
|
|
INSERT INTO train_training_site SELECT * FROM bak_v1_train_training_site;
|
|
INSERT INTO train_class_plan SELECT * FROM bak_v1_train_class_plan;
|
|
INSERT INTO train_dormitory_info SELECT * FROM bak_v1_train_dormitory_info;
|
|
INSERT INTO train_electronic_board SELECT * FROM bak_v1_train_electronic_board;
|
|
INSERT INTO train_dorm_auth SELECT * FROM bak_v1_train_dorm_auth;
|
|
INSERT INTO train_class_report SELECT * FROM bak_v1_train_class_report;
|
|
INSERT INTO train_student_checkin SELECT * FROM bak_v1_train_student_checkin;
|
|
INSERT INTO train_study_duration SELECT * FROM bak_v1_train_study_duration;
|
|
INSERT INTO train_student_portrait SELECT * FROM bak_v1_train_student_portrait;
|
|
|
|
-- 步骤 6: 校验教师唯一数据还原结果
|
|
DO $$
|
|
DECLARE
|
|
v_cnt INT;
|
|
BEGIN
|
|
SELECT count(*) INTO v_cnt FROM train_teacher;
|
|
IF v_cnt <> 1 THEN
|
|
RAISE EXCEPTION '>>> [Rollback-FATAL] 教师数据还原失败: 期望 1 行,实际为 % 行', v_cnt;
|
|
END IF;
|
|
RAISE NOTICE '>>> [Rollback-PASS] 13 张表结构与教师数据已严格依据 Phase 0.5 标准 DDL 恢复完毕。';
|
|
END $$;
|
|
|
|
COMMIT;
|