需要向表中添加FK约束,同时保持现有数据与另一个表

时间:2016-02-02 17:22:51

标签: sql database tsql database-design relational-database

我目前有这个架构,以及两个表中的一些数据:

       animal table                   pet_accessories table
+---------------+---------+   +-----------------------+-----------+
|  animal_key   |   type  |   |  pet_accessories_key  |   animal  |
+---------------+---------+   +-----------------------+-----------+
|      1        |   Dog   |   |           1           |   Dog     |
|      2        |   Cat   |   |           2           |   Bird    |
|      3        |   Bird  |   |           3           |   Cat     |   
+---------------+---------+   |           4           |   Cat     | 
                              +-----------------------+-----------+

但需要在具有FK约束的表之间添加从pet_accessories到动物表的关系。最终,这就是我所需要的:

       animal table                   pet_accessories table
+---------------+---------+   +-----------------------+---------------+
|  animal_key   |   type  |   |  pet_accessories_key  |   animal_key  |
+---------------+---------+   +-----------------------+---------------+
|      1        |   Dog   |   |           1           |       1       |
|      2        |   Cat   |   |           2           |       3       |
|      3        |   Bird  |   |           3           |       2       |   
+---------------+---------+   |           4           |       2       | 
                              +-----------------------+---------------+

我尝试在现有的pet_accessories表中添加一个新的键列,但是在正确设置此animal_key的逻辑上遇到了问题:

+-----------------------+-----------+--------------+
|  pet_accessories_key  |   animal  |  animal_key  |
+-----------------------+-----------+--------------+
|           1           |   Dog     |              |
|           2           |   Bird    |              |
|           3           |   Cat     |              | 
|           4           |   Cat     |              |
+-----------------------+-----------+--------------+ 

我知道SQL主要是一种面向集合的语言 - 在其中使用循环通常是一个坏主意。我还读过,我可能会使用游标,虽然我对它们不太熟悉。

问题是,在pet_accessories.animal中循环数据并与animals.type进行比较的最佳方法是什么,这样我最终可以为所有现有的pet_accessories记录设置pet_accessories.animal_key = animal.animal_key?换句话说,我该怎么做:

for each record in pet_accessories
  for each record in animal
    if pet_accessories.animal == animal.type
      then pet_accessories.animal_key = animal_animal_key

1 个答案:

答案 0 :(得分:2)

首先,添加列:

alter table pet_accessories add animal_key integer;

然后,更新列:

update pa
    set animal_key = a.animal_key
    from pet_accessories pa join
         animals a
         on pa.animal = a.type;

然后,检查以确保一切都符合您的要求。

然后,删除旧列:

alter table pet_accessories drop column animal;

然后添加外键约束:

alter table add constraint fk_animal_key
    foreign key (animal_key) references animal(animal_key);