使来自多个表的查询更短和优化
Make query from multiple tables shorter and optimized
我在 Java 中使用 PreparedStatement。我有一个来自多个表的 sql 查询。如果可能的话,我怎样才能使这个查询更短和优化?数据库是 "Oracle 12c database"。我的任务也是使查询 sql-注入安全并防止注入。
preparedStatement = connection.prepareStatement("delete from " +
"TBL_ORG_DATA, " +
"TBL_ORG_CONTACTS, " +
"TBL_HEALTH_SERVICE, " +
"TBL_EDUCATION, " +
"TBL_LENGTH_WORK, " +
"TBL_CONTRACTS, " +
"TBL_EVENTS, " +
"TBL_TRADE_UNIONS, " +
"TBL_COMMITTEES, " +
"TBL_HEALTH_CHECK, " +
"TBL_ACCIDENTS, " +
"TBL_VICTIMS, " +
"TBL_ACCIDENTS_DAMAGE, " +
"TBL_ATTESTATION, " +
"TBL_ATTESTATION_FIVE_YEAR, " +
"TBL_TRANING, " +
"TBL_TRAINING_MANAGER, " +
"TBL_TRANING_THREE_YEAR, " +
"TBL_MANAGEMENT " +
"where TBL_ORG_DATA.ORG_ID = ? AND\n" +
"TBL_ORG_CONTACTS.ORG_ID = ? AND\n" +
"TBL_HEALTH_SERVICE.ORG_ID = ? AND\n" +
"TBL_EDUCATION.ORG_ID = ? AND\n" +
"TBL_LENGTH_WORK.ORG_ID = ? AND\n" +
"TBL_CONTRACTS.ORG_ID = ? AND\n" +
"TBL_EVENTS.ORG_ID = ? AND\n" +
"TBL_TRADE_UNIONS.ORG_ID = ? AND\n" +
"TBL_COMMITTEES.ORG_ID = ? AND\n" +
"TBL_HEALTH_CHECK.ORG_ID = ? AND\n" +
"TBL_ACCIDENTS.ORG_ID = ? AND\n" +
"TBL_VICTIMS.ORG_ID = ? AND\n" +
"TBL_ACCIDENTS_DAMAGE.ORG_ID = ? AND\n" +
"TBL_ATTESTATION.ORG_ID = ? AND\n" +
"TBL_ATTESTATION_FIVE_YEAR.ORG_ID = ? AND\n" +
"TBL_TRANING.ORG_ID = ? AND\n" +
"TBL_TRAINING_MANAGER.ORG_ID = ? AND\n" +
"TBL_TRANING_THREE_YEAR.ORG_ID = ? AND\n" +
"TBL_MANAGEMENT.ORG_ID = ? AND\n" +
"TBL_ORG_DATA.DATE_PERIOD = ? AND\n" +
"TBL_ORG_CONTACTS.DATE_PERIOD = ? AND\n" +
"TBL_HEALTH_SERVICE.DATE_PERIOD= ? AND\n" +
"TBL_EDUCATION.DATE_PERIOD= ? AND\n" +
"TBL_LENGTH_WORK.DATE_PERIOD = ? AND\n" +
"TBL_CONTRACTS.DATE_PERIOD = ? AND\n" +
"TBL_EVENTS.DATE_PERIOD = ? AND\n" +
"TBL_TRADE_UNIONS.DATE_PERIOD = ? AND\n" +
"TBL_COMMITTEES.DATE_PERIOD = ? AND\n" +
"TBL_HEALTH_CHECK.DATE_PERIOD = ? AND\n" +
"TBL_ACCIDENTS.DATE_PERIOD = ? AND\n" +
"TBL_VICTIMS.DATE_PERIOD = ? AND\n" +
"TBL_ACCIDENTS_DAMAGE.DATE_PERIOD = ? AND\n" +
"TBL_ATTESTATION.DATE_PERIOD = ? AND\n" +
"TBL_ATTESTATION_FIVE_YEAR.DATE_PERIOD = ? AND\n" +
"TBL_TRANING.DATE_PERIOD = ? AND\n" +
"TBL_TRAINING_MANAGER.DATE_PERIOD = ? AND\n" +
"TBL_TRANING_THREE_YEAR.DATE_PERIOD = ? AND\n" +
"TBL_MANAGEMENT.DATE_PERIOD = ?");
据我所知,在 Oracle 中您必须为每个 table 创建单独的 delete
命令。
delete from a where org_id = 101 and date_period = date '2018-05-25';
delete from b where org_id = 101 and date_period = date '2018-05-25';
如果您可以修改 table,那么您也许可以使用约束 on delete cascade
。我不知道您的 table 是如何组织的,但是如果您可以在其中一个中定义唯一约束,那么其余的可能取决于它,如下所示:
create table a (
id number primary key, org_id number, date_period date, cola varchar2(5),
constraint uq_org_id_period unique (org_id, date_period) );
insert into a values (1, 101, date '2018-05-25', 'DEL');
insert into a values (2, 101, date '2018-05-26', 'PQR');
insert into a values (3, 102, date '2018-06-17', 'CBA');
create table b (
id number primary key, org_id number, date_period date, colb varchar2(5),
constraint fk_org_id_period
foreign key (org_id, date_period)
references a(org_id, date_period) on delete cascade);
insert into b values (1, 101, date '2018-05-26', 'AAXXX');
insert into b values (2, 102, date '2018-06-17', 'PCCQR');
insert into b values (3, 101, date '2018-05-25', 'DEL1');
insert into b values (4, 101, date '2018-05-25', 'DEL2');
insert into b values (5, 102, date '2018-06-17', 'XYZYX');
现在如果你 运行:
delete from a where (org_id, date_period) in ((101, date '2018-05-25'));
不仅 table a
中的第 1 行将被删除,b
中的第 3 行和第 4 行也会被删除。您也可以使用触发器,但这里使用约束更合适。
我在 Java 中使用 PreparedStatement。我有一个来自多个表的 sql 查询。如果可能的话,我怎样才能使这个查询更短和优化?数据库是 "Oracle 12c database"。我的任务也是使查询 sql-注入安全并防止注入。
preparedStatement = connection.prepareStatement("delete from " +
"TBL_ORG_DATA, " +
"TBL_ORG_CONTACTS, " +
"TBL_HEALTH_SERVICE, " +
"TBL_EDUCATION, " +
"TBL_LENGTH_WORK, " +
"TBL_CONTRACTS, " +
"TBL_EVENTS, " +
"TBL_TRADE_UNIONS, " +
"TBL_COMMITTEES, " +
"TBL_HEALTH_CHECK, " +
"TBL_ACCIDENTS, " +
"TBL_VICTIMS, " +
"TBL_ACCIDENTS_DAMAGE, " +
"TBL_ATTESTATION, " +
"TBL_ATTESTATION_FIVE_YEAR, " +
"TBL_TRANING, " +
"TBL_TRAINING_MANAGER, " +
"TBL_TRANING_THREE_YEAR, " +
"TBL_MANAGEMENT " +
"where TBL_ORG_DATA.ORG_ID = ? AND\n" +
"TBL_ORG_CONTACTS.ORG_ID = ? AND\n" +
"TBL_HEALTH_SERVICE.ORG_ID = ? AND\n" +
"TBL_EDUCATION.ORG_ID = ? AND\n" +
"TBL_LENGTH_WORK.ORG_ID = ? AND\n" +
"TBL_CONTRACTS.ORG_ID = ? AND\n" +
"TBL_EVENTS.ORG_ID = ? AND\n" +
"TBL_TRADE_UNIONS.ORG_ID = ? AND\n" +
"TBL_COMMITTEES.ORG_ID = ? AND\n" +
"TBL_HEALTH_CHECK.ORG_ID = ? AND\n" +
"TBL_ACCIDENTS.ORG_ID = ? AND\n" +
"TBL_VICTIMS.ORG_ID = ? AND\n" +
"TBL_ACCIDENTS_DAMAGE.ORG_ID = ? AND\n" +
"TBL_ATTESTATION.ORG_ID = ? AND\n" +
"TBL_ATTESTATION_FIVE_YEAR.ORG_ID = ? AND\n" +
"TBL_TRANING.ORG_ID = ? AND\n" +
"TBL_TRAINING_MANAGER.ORG_ID = ? AND\n" +
"TBL_TRANING_THREE_YEAR.ORG_ID = ? AND\n" +
"TBL_MANAGEMENT.ORG_ID = ? AND\n" +
"TBL_ORG_DATA.DATE_PERIOD = ? AND\n" +
"TBL_ORG_CONTACTS.DATE_PERIOD = ? AND\n" +
"TBL_HEALTH_SERVICE.DATE_PERIOD= ? AND\n" +
"TBL_EDUCATION.DATE_PERIOD= ? AND\n" +
"TBL_LENGTH_WORK.DATE_PERIOD = ? AND\n" +
"TBL_CONTRACTS.DATE_PERIOD = ? AND\n" +
"TBL_EVENTS.DATE_PERIOD = ? AND\n" +
"TBL_TRADE_UNIONS.DATE_PERIOD = ? AND\n" +
"TBL_COMMITTEES.DATE_PERIOD = ? AND\n" +
"TBL_HEALTH_CHECK.DATE_PERIOD = ? AND\n" +
"TBL_ACCIDENTS.DATE_PERIOD = ? AND\n" +
"TBL_VICTIMS.DATE_PERIOD = ? AND\n" +
"TBL_ACCIDENTS_DAMAGE.DATE_PERIOD = ? AND\n" +
"TBL_ATTESTATION.DATE_PERIOD = ? AND\n" +
"TBL_ATTESTATION_FIVE_YEAR.DATE_PERIOD = ? AND\n" +
"TBL_TRANING.DATE_PERIOD = ? AND\n" +
"TBL_TRAINING_MANAGER.DATE_PERIOD = ? AND\n" +
"TBL_TRANING_THREE_YEAR.DATE_PERIOD = ? AND\n" +
"TBL_MANAGEMENT.DATE_PERIOD = ?");
据我所知,在 Oracle 中您必须为每个 table 创建单独的 delete
命令。
delete from a where org_id = 101 and date_period = date '2018-05-25';
delete from b where org_id = 101 and date_period = date '2018-05-25';
如果您可以修改 table,那么您也许可以使用约束 on delete cascade
。我不知道您的 table 是如何组织的,但是如果您可以在其中一个中定义唯一约束,那么其余的可能取决于它,如下所示:
create table a (
id number primary key, org_id number, date_period date, cola varchar2(5),
constraint uq_org_id_period unique (org_id, date_period) );
insert into a values (1, 101, date '2018-05-25', 'DEL');
insert into a values (2, 101, date '2018-05-26', 'PQR');
insert into a values (3, 102, date '2018-06-17', 'CBA');
create table b (
id number primary key, org_id number, date_period date, colb varchar2(5),
constraint fk_org_id_period
foreign key (org_id, date_period)
references a(org_id, date_period) on delete cascade);
insert into b values (1, 101, date '2018-05-26', 'AAXXX');
insert into b values (2, 102, date '2018-06-17', 'PCCQR');
insert into b values (3, 101, date '2018-05-25', 'DEL1');
insert into b values (4, 101, date '2018-05-25', 'DEL2');
insert into b values (5, 102, date '2018-06-17', 'XYZYX');
现在如果你 运行:
delete from a where (org_id, date_period) in ((101, date '2018-05-25'));
不仅 table a
中的第 1 行将被删除,b
中的第 3 行和第 4 行也会被删除。您也可以使用触发器,但这里使用约束更合适。