【问题标题】:Make query from multiple tables shorter and optimized使来自多个表的查询更短且优化
【发布时间】:2018-08-01 07:23:57
【问题描述】:

我在 Java 中使用 PreparedStatement。我有来自多个表的 sql 查询。如果可能的话,我怎样才能使这个查询更短和优化? DB 是“Oracle 12c 数据库”。另外我的任务是使查询 sql-injection 安全并防止注入。

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 = ?");

【问题讨论】:

  • from 部分中有许多表,现在在where 中加入子句。对我来说似乎不合适。这些表是否以某种方式相互关联
  • 对不起,我弄错了。在这个查询中,我应该使用“删除”而不是“选择”。这些表具有相同的字段:ORG_ID、DATE_PERIOD。
  • 您当前的DELETE 有什么问题需要解决?
  • @MickMnemonic 查询很大,字符串会重复很多次。是否存在重新制作此查询的方法?
  • 您正在从大约 20 个表中删除数据,所以是的,SQL 会很长。我个人会将这些拆分为单独的 DELETE,但在不了解您的数据库架构的情况下,很难给出建议。

标签: java sql oracle jdbc multiple-tables


【解决方案1】:

据我所知,您必须为每个表创建单独的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';

如果您可以修改表,那么您可以使用约束on delete cascade。我不知道您的表是如何组织的,但是如果您可以在其中一个表中定义唯一约束,那么其余的可能取决于它,如下所示:

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'));

不仅表 a 中的第 1 行将被删除,b 中的第 3 行和第 4 行也将被删除。您也可以使用触发器,但这里更适合使用约束。

【讨论】:

  • 感谢您的回复。不幸的是,在我的数据库中应用“级联删除”并非不可能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多