2012-10-15 51 views
6

假设我有两个表格:CustomerCity。有很多Customer住在同一个City。这些城市的主要关键是uid。客户通过Customer.city_uid可以获得对各自城市的外部参照。如何更改postgresql中的外键值?

由于外在原因,我必须互相交换两个City.uid。但客户应该留在他们的城市。因此有必要更换Customer.city_uid。所以我想我先交换City.uid s,然后通过UPDATE -statement更改Customer.city_uid s。不幸的是,我不能这样做,因为这些uids引用自Customer -table,PostgreSQL阻止我这样做。

是否有简单的方法将两个City.uid与另一个以及Customer.city_uid s交换?

+0

如果您有N个引用“主”(在您的情况下为城市)表中的表格,则问题会变得更大。到目前为止,这是我最喜欢的解决方案:http://stackoverflow.com/a/18273069/633961(但我仍然在寻找更好的方法来解决这个问题)。 – guettli

回答

1

我的直觉是建议不要试图改变city表的id字段。但是这里缺少很多信息。所以它真的是感觉而不是权威的观点。

相反,我会交换值在等领域city。例如,将city1的名称更改为city2的名称,反之亦然。

例如:

OLD TABLE        NEW TABLE 

id | name | population     id | name | population 
-------------------------    ------------------------- 
    1 | ABerg | 123456      1 | BBerg | 654321 
    2 | BBerg | 654321      2 | ABerg | 123456 
    3 | CBerg | 333333      3 | CBerg | 333333 

(该ID并没有被感动,但其他值交换功能也可以交换的ID,但是这并不需要“更软接触”查询。做任何修改表约束等)


然后,在你的相关表格,你可以做...

UPDATE 
    Customer 
SET 
    city_uid = CASE WHEN city_uid = 1 THEN 2 ELSE 1 END 
WHERE 
    city_uid IN (1,2) 

但是,那么您是否还有其他表格引用city_uid?如果是这样,你可以在所有这些表格上重复更新吗?

+0

但是,谢谢你,这是不可能的。我真的需要改变uid。 – AME

+0

你能解释更多吗?如果“uid = 1”现在与“uid = 2”曾经拥有的城市名称等相关联,那么您是否做过同样的事情?这个问题在哪些方面不足?只是为了我们可以提出替代解决方案。 – MatBailie

+0

添加了一个可视化示例,显示交换名称等功能与交换ID字段相同。 – MatBailie

4

一种解决方案可能是:

BEGIN; 
1. Drop foreign key 
2. Make update 
3. Create foreign key 
COMMIT; 

或者:

BEGIN; 
1. Insert "new" correct information 
2. Remove outdated information 
COMMIT; 
1

您可以创建两个临时的城市。

你必须:

  • 市1
  • 市2
  • 城市气温1
  • 城市气温2

然后,你可以做如下:

  1. 名更新所有客户的UID从市1至城市气温1
  2. 更新所有客户的UID从市2到城市气温2
  3. 交换城市1和2的UID
  4. 移动从城市气温1所有客户回城1.
  5. 将所有客户从城市温度2移回城市2.
  6. 删除暂时的城市。