首先让我描述一下这种情况:
假设我有两个表“ PRODUCTS”和“ CUSTOMERS”,其描述如下:
产品表:
+----------+
| PRODUCTS |
+----------+
| ID |
| CARD_ID |
+----------+
和CUSTOMERS表:
+-----------+
| CUSTOMERS |
+-----------+
| ID |
| APP_ID |
| CARD_ID |
+-----------+
所有这些字段都是数字类型。
这两个表相当大,已经包含了大量数据。在CUSTOMERS表中,CARD_ID与PRODUCTS表中的CARD_ID是相同的。这些表之间存在一对一的关系,即,一个客户只能使用一个CARD_ID,而一个以上客户不能使用任何CARD_ID。但是某些客户可能还没有使用过任何产品,即,其CARD_ID为空。
我想在我们的PRODUCTS表中为CUSTOMERS表添加一个反向引用(出于应用目的)。所以我做了类似的事情:
ALTER TABLE PRODUCTS ADD CUSTOMER_ID NUMBER DEFAULT -1 NOT NULL;
现在,由于已经存在数据,因此我还需要编写一个迁移查询。也就是说,如果客户使用的是ID为C的卡,那么我需要在C的客户ID字段中为所有此类现有匹配项添加该客户ID。
我曾经想过用类似的这个,但我的理解是,内选择查询这里是一个内部联接,所以我不知道是否会在这种情况下是有效的。
我也虽然使用了“ with”子句,但我认为“ with”仅适用于选择查询。[UPDATE]使用“ with”子句找到了它,但这是一个好方法吗?
帮我弄清楚应该如何有效地做到这一点。例如,我现在不希望任何客户都没有使用的PRODUCTS中的行进行更新。
数据库:Oracle 12c。
提前致谢。
[编辑]只是想提一下,我最终为此使用了PL / SQL。在PL / SQL中,这非常容易。此外,对于我们来说,更容易通过飞行路线迁移系统进行处理。
DECLARE
CURSOR C IS SELECT customer.APP_ID, customer.CARD_ID FROM CUSTOMERS customer INNER JOIN PRODUCTS prod on customer.CARD_ID = prod.CARD_ID;
BEGIN
FOR rec IN C
LOOP
UPDATE PRODUCTS p SET p.CUSTOMER_ID = rec.APP_ID WHERE p.CUSTOMER_ID is null and p.CARD_ID = rec.CARD_ID;
END LOOP;
END;
这是完成工作的另一种方式。这适合于我的特定应用程序。这是最好的方法吗?可能是,可能不是!
我同意您应避免更新产品表。我什至不会在其中添加customer_id列:它不仅会导致对customers.card_id列的更新花费更多时间-因为它还需要同时更新产品表-甚至可能导致不一致如果实施不防水。
相反,我建议创建一个将customer_id与产品列连接在一起的数据库视图:
create view vw_products as
select products.id, products.card_id, customers.customer_id
from products
inner join customers
on customers.card_id = products.card_id;
这样,您实际上并不需要存储customer_id,而是可以select
从此视图而不是原始的product表中获取所需的内容。此外,无需对表数据进行任何迁移。
即使有大量数据,如果您在两个表的card_id列上都定义了索引,这也将很好地执行。
如果由于某些原因您确实需要将customer_id列添加到产品表中,则按如下所示更新该新列:
UPDATE products
SET customer_id = (
SELECT customer_id
FROM customers
WHERE customers.card_id = products.card_id);
注意:此数据库设计看起来违反直觉:客户与产品之间的一对一关系是该企业破产的保证。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句