如何修改一个select SQL查询以在Oracle数据库中执行删除查询?

huangapple go评论62阅读模式
英文:

How to modify a select sql query to do a delete query with oracle db?

问题

我需要一些关于我的SQL脚本的帮助。我最初根据我们的SQL Excel报告制定了它,以便我还能看到将在我的选择查询中删除的行。根据要求进行了修改后,我终于能够看到需要删除的适当行。

然而,显然,将选择查询转换为删除查询很困难。由于我已经有将近两年没有使用SQL脚本/命令了,我再次成为SQL脚本的新手。有人可以帮我将下面的选择查询转换为删除查询吗?

SELECT
tcca.*
FROM
portraitowner.business_traveler bt
INNER JOIN portraitowner.client_org_unit cou ON bt.client_org_unit_top_id = cou.client_org_unit_id
AND bt.client_org_unit_top_orig_id = cou.client_org_unit_orig_id
INNER JOIN portraitowner.client_org_unit cous ON bt.client_org_unit_sub_id = cous.client_org_unit_id
AND bt.client_org_unit_sub_orig_id = cous.client_org_unit_orig_id
LEFT JOIN portraitowner.traveler_e_mail_address tema ON bt.business_traveler_id = tema.business_traveler_id
AND bt.business_traveler_orig_id = tema.business_traveler_orig_id AND tema.e_mail_address_type_code = 1
INNER JOIN portraitowner.traveler_credit_card tcc ON bt.business_traveler_id = tcc.business_traveler_id
AND bt.business_traveler_orig_id = tcc.business_traveler_orig_id
INNER JOIN portraitowner.TRAVELER_CC_AUTHENTICATION tcca ON tcc.TRAVELER_CREDIT_CARD_ID = tcca.TRAVELER_CREDIT_CARD_ID
AND tcc.TRAVELER_CREDIT_CARD_ORIG_ID = tcca.TRAVELER_CREDIT_CARD_ORIG_ID
LEFT JOIN portraitowner.TRAVELER_CC_ROLLUP tcr ON tcc.traveler_credit_card_id = tcr.traveler_credit_card_id
AND tcc.traveler_credit_card_orig_id = tcr.traveler_credit_card_orig_id
AND bt.business_traveler_id = tcr.traveler_cc_auth_id
AND bt.business_traveler_orig_id = tcr.traveler_cc_auth_orig_id
WHERE
cous.localization_country_code = 'IN'
AND
tcc.LAST_MODIFIED_TS > tcca.LAST_MODIFIED_TS
AND SYSDATE - 7 > tcca.LAST_MODIFIED_TS

上面的脚本是从tcc表查询,并在tcca表中搜索相关的子记录。
tcc就像一种支付形式的记录
tcca就像令牌的记录。
当支付方式更新,使tcca令牌比tcca表中的令牌更旧时,我们需要删除tcca表中的令牌。我们在7天后删除这些匹配条件。至于内连接等,这些来自原始SQL报告,我不确定是否在删除查询中仍然需要这些。但我确定的一件事是,这个选择查询已经足够我删除tcca表中的记录,因为我可以看到这里设置的条件将被删除的行。

问题是,我无法将其转换为删除查询。已经按照delete from * in ([选择查询放在这里]) [这里等] 进行了尝试。但是我也无法使它在那里工作,因为我不知道如何在删除查询中放置表格。

英文:

I need some help in my sql script. I initially patterned it with our sql excel report so that I could also see the rows that would be deleted with my select query. After modifying it based on the requirements. I could finally see the appropriate rows that needs to be deleted.

However, apparently, converting a select query to delete query is hard. I am already a novice in sql scripting again as I have not been using sql scripts/commands for almost 2 years now. Can anyone help me convert this select query below to a delete query?.

SELECT  
tcca.*             
FROM 
portraitowner.business_traveler bt INNER JOIN portraitowner.client_org_unit cou ON bt.client_org_unit_top_id = cou.client_org_unit_id
AND     bt.client_org_unit_top_orig_id = cou.client_org_unit_orig_id INNER JOIN portraitowner.client_org_unit cous ON bt.client_org_unit_sub_id = cous.client_org_unit_id
AND     bt.client_org_unit_sub_orig_id = cous.client_org_unit_orig_id LEFT JOIN portraitowner.traveler_e_mail_address tema ON bt.business_traveler_id = tema.business_traveler_id
AND     bt.business_traveler_orig_id = tema.business_traveler_orig_id AND tema.e_mail_address_type_code = 1 INNER JOIN portraitowner.traveler_credit_card tcc ON bt.business_traveler_id = tcc.business_traveler_id
AND     bt.business_traveler_orig_id = tcc.business_traveler_orig_id INNER JOIN portraitowner.TRAVELER_CC_AUTHENTICATION tcca ON tcc.TRAVELER_CREDIT_CARD_ID = tcca.TRAVELER_CREDIT_CARD_ID
AND     tcc.TRAVELER_CREDIT_CARD_ORIG_ID = tcca.TRAVELER_CREDIT_CARD_ORIG_ID LEFT JOIN portraitowner.TRAVELER_CC_ROLLUP tcr ON tcc.traveler_credit_card_id = tcr.traveler_credit_card_id
AND     tcc.traveler_credit_card_orig_id = tcr.traveler_credit_card_orig_id
AND     bt.business_traveler_id = tcr.traveler_cc_auth_id
AND     bt.business_traveler_orig_id = tcr.traveler_cc_auth_orig_id
WHERE 
cous.localization_country_code = 'IN'
AND 
tcc.LAST_MODIFIED_TS > tcca.LAST_MODIFIED_TS
AND SYSDATE - 7 > tcca.LAST_MODIFIED_TS  

What the script above does is query from tcc table and search for related child record in the tcca table.
tcc is like a record of form of payments
tcca is like the records of tokens.
We need to delete the tokens from tcca table when the form of payment is updated which makes the tcca tokens more older than the ones in the tcca table. We delete this matching conditions after 7 days. Now as for the inner joins etc this came from the original sql report and I am not sure if this will still be needed for the delete query. But one thing I am sure is that this select query is what I already need for deleting records on the tcca table as I could see the rows that will be deleted with the conditions set here.

Problem is, I can't quite convert it to a delete query. Already followed the delete from * in ([select query is placed here]) here etc. Yet I can't make it work too there as I dont know to place on the tables from delete query.

答案1

得分: 2

DELETE with ROWID IN 在大多数情况下效果很好。如果您的数据非常庞大,另一个可以利用并行处理的选项是 MERGE

MERGE /*+ enable_parallel_dml parallel(8) */ INTO portraitowner.TRAVELER_CC_AUTHENTICATION tgt
USING (SELECT /*+ parallel(8) */ tcca.ROWID AS row_id       
         FROM 
              portraitowner.business_traveler bt INNER JOIN portraitowner.client_org_unit cou ON bt.client_org_unit_top_id = cou.client_org_unit_id
              AND     bt.client_org_unit_top_orig_id = cou.client_org_unit_orig_id INNER JOIN portraitowner.client_org_unit cous ON bt.client_org_unit_sub_id = cous.client_org_unit_id
              AND     bt.client_org_unit_sub_orig_id = cous.client_org_unit_orig_id LEFT JOIN portraitowner.traveler_e_mail_address tema ON bt.business_traveler_id = tema.business_traveler_id
              AND     bt.business_traveler_orig_id = tema.business_traveler_orig_id AND tema.e_mail_address_type_code = 1 INNER JOIN portraitowner.traveler_credit_card tcc ON bt.business_traveler_id = tcc.business_traveler_id
              AND     bt.business_traveler_orig_id = tcc.business_traveler_orig_id INNER JOIN portraitowner.TRAVELER_CC_AUTHENTICATION tcca ON tcc.TRAVELER_CREDIT_CARD_ID = tcca.TRAVELER_CREDIT_CARD_ID
              AND     tcc.TRAVELER_CREDIT_CARD_ORIG_ID = tcca.TRAVELER_CREDIT_CARD_ORIG_ID LEFT JOIN portraitowner.TRAVELER_CC_ROLLUP tcr ON tcc.traveler_credit_card_id = tcr.traveler_credit_card_id
              AND     tcc.traveler_credit_card_orig_id = tcr.traveler_credit_card_orig_id
              AND     bt.business_traveler_id = tcr.traveler_cc_auth_id
              AND     bt.business_traveler_orig_id = tcr.traveler_cc_auth_orig_id
              WHERE 
              cous.localization_country_code = 'IN'
              AND 
              tcc.LAST_MODIFIED_TS > tcca.LAST_MODIFIED_TS
              AND SYSDATE - 7 > tcca.LAST_MODIFIED_TS) src
 ON (src.row_id = tgt.ROWID)
WHEN MATCHED THEN UPDATE SET tgt.LAST_MODIFIED_TS = tgt.LAST_MODIFIED_TS
                  DELETE WHERE 1=1;

这使您可以在SELECT部分使用哈希连接,并将结果传递到并行化的删除步骤。不幸的是,为了满足语法要求并进入MERGE的UPDATE子程序中进行DELETE,它确实需要在随机列上执行虚假的UPDATE SET 操作。

英文:

DELETE with ROWID IN works great in most cases. Another option that can utilize parallelism if your data is massive is MERGE:

MERGE /*+ enable_parallel_dml parallel(8) */ INTO portraitowner.TRAVELER_CC_AUTHENTICATION tgt
USING (SELECT /*+ parallel(8) */ tcca.ROWID AS row_id       
         FROM 
              portraitowner.business_traveler bt INNER JOIN portraitowner.client_org_unit cou ON bt.client_org_unit_top_id = cou.client_org_unit_id
              AND     bt.client_org_unit_top_orig_id = cou.client_org_unit_orig_id INNER JOIN portraitowner.client_org_unit cous ON bt.client_org_unit_sub_id = cous.client_org_unit_id
              AND     bt.client_org_unit_sub_orig_id = cous.client_org_unit_orig_id LEFT JOIN portraitowner.traveler_e_mail_address tema ON bt.business_traveler_id = tema.business_traveler_id
              AND     bt.business_traveler_orig_id = tema.business_traveler_orig_id AND tema.e_mail_address_type_code = 1 INNER JOIN portraitowner.traveler_credit_card tcc ON bt.business_traveler_id = tcc.business_traveler_id
              AND     bt.business_traveler_orig_id = tcc.business_traveler_orig_id INNER JOIN portraitowner.TRAVELER_CC_AUTHENTICATION tcca ON tcc.TRAVELER_CREDIT_CARD_ID = tcca.TRAVELER_CREDIT_CARD_ID
              AND     tcc.TRAVELER_CREDIT_CARD_ORIG_ID = tcca.TRAVELER_CREDIT_CARD_ORIG_ID LEFT JOIN portraitowner.TRAVELER_CC_ROLLUP tcr ON tcc.traveler_credit_card_id = tcr.traveler_credit_card_id
              AND     tcc.traveler_credit_card_orig_id = tcr.traveler_credit_card_orig_id
              AND     bt.business_traveler_id = tcr.traveler_cc_auth_id
              AND     bt.business_traveler_orig_id = tcr.traveler_cc_auth_orig_id
              WHERE 
              cous.localization_country_code = 'IN'
              AND 
              tcc.LAST_MODIFIED_TS > tcca.LAST_MODIFIED_TS
              AND SYSDATE - 7 > tcca.LAST_MODIFIED_TS) src
 ON (src.row_id = tgt.ROWID)
WHEN MATCHED THEN UPDATE SET tgt.LAST_MODIFIED_TS = tgt.LAST_MODIFIED_TS
                  DELETE WHERE 1=1;

This allows you to use hash joins in the SELECT portion and feed the results into parallelized delete step. Unfortunately it does require a bogus UPDATE SET on a random column in order to satisfy the syntax requirements and get to the DELETE which happens within the UPDATE subprogram of MERGE.

答案2

得分: 1

在一般情况下,您可以在ROWID伪列上进行相关操作(它实际上是指向数据文件中行的位置的指针)。

所以查询将是:

DELETE FROM portraitowner.TRAVELER_CC_AUTHENTICATION
WHERE  ROWID IN (
  SELECT tcca.ROWID
  FROM   <your big join query>
  WHERE  <your filter conditions>
)

您可能能够删除一些或全部LEFT OUTER JOIN,但如果查询性能合理且返回您想要删除的行的选择,则修改查询并重新验证输出可能比直接使用子查询更麻烦。

英文:

In general, you can correlate on the ROWID pseudo-column (which is effectively a pointer to the location of the row in the data file).

So the query would be:

DELETE FROM portraitowner.TRAVELER_CC_AUTHENTICATION
WHERE  ROWID IN (
  SELECT tcca.ROWID
  FROM   <your big join query>
  WHERE  <your filter conditions>
)

You may be able to remove some/all of the LEFT OUTER JOINs but if the query is reasonably performant and is returning the selection of rows that you want to remove then it may be more hassle to modify the query and re-validate the output than it is just to use the sub-query as-is.

答案3

得分: 1

从 portraitowner.TRAVELER_CC_AUTHENTICATION 表中删除记录,条件为:7天前的记录,且相关条件满足。这个删除语句的性能比在 PL/SQL 中逐行获取 rowid 并逐行删除或者批量获取一定数量的记录再批量删除要好。

英文:
delete from  portraitowner.TRAVELER_CC_AUTHENTICATION tcca
where SYSDATE - 7 > tcca.LAST_MODIFIED_TS
  and exists (
    select 1
    FROM portraitowner.business_traveler bt 
    INNER JOIN portraitowner.client_org_unit cou ON bt.client_org_unit_top_id = cou.client_org_unit_id
      AND     bt.client_org_unit_top_orig_id = cou.client_org_unit_orig_id 
    INNER JOIN portraitowner.client_org_unit cous ON bt.client_org_unit_sub_id = cous.client_org_unit_id
      AND     bt.client_org_unit_sub_orig_id = cous.client_org_unit_orig_id 
    LEFT JOIN portraitowner.traveler_e_mail_address tema ON bt.business_traveler_id = tema.business_traveler_id
      AND     bt.business_traveler_orig_id = tema.business_traveler_orig_id AND tema.e_mail_address_type_code = 1 
    INNER JOIN portraitowner.traveler_credit_card tcc ON bt.business_traveler_id = tcc.business_traveler_id
      AND     bt.business_traveler_orig_id = tcc.business_traveler_orig_id 
    LEFT JOIN portraitowner.TRAVELER_CC_ROLLUP tcr ON tcc.traveler_credit_card_id = tcr.traveler_credit_card_id
      AND     tcc.traveler_credit_card_orig_id = tcr.traveler_credit_card_orig_id
      AND     bt.business_traveler_id = tcr.traveler_cc_auth_id
      AND     bt.business_traveler_orig_id = tcr.traveler_cc_auth_orig_id
    WHERE cous.localization_country_code = 'IN'
      AND tcc.LAST_MODIFIED_TS > tcca.LAST_MODIFIED_TS      
      and tcc.TRAVELER_CREDIT_CARD_ID = tcca.TRAVELER_CREDIT_CARD_ID
      AND tcc.TRAVELER_CREDIT_CARD_ORIG_ID = tcca.TRAVELER_CREDIT_CARD_ORIG_ID

);

I'd go for this one delete statement which would perform better than actually fetching in PL/SQL the rowid for each row in that select and deleting row by row, or, eventually bulk collecting with a limit and deleting in bulks.

huangapple
  • 本文由 发表于 2023年5月22日 20:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306018.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定