1

我有几个表可以从某些日志中自动获取数据。例如,假设我的表由两列组成:

Country | someData
--------|---------
USA     | 123
Canada  | 4545
Mexico  | 4363
USA     | 3434
...

现在我在 Country 列中有很多重复,因此使用外键和另一个表来表示 Country 是有意义的,但不幸的是,数据上传到表中的方式,我无法实现。插入数据的程序会插入 Country 字符串,我无法更改(例如 INSERT INTO table VALUES ('USA',3232))

我想知道是否有办法让表自动维护某种关系,这样它就不会多次存储相同的字符串。

谢谢

4

3 回答 3

0

我不能保证这遵循了我刚刚了解到的最佳实践,但是我不时会遇到这种需求,我一直想学习这一点,所以我认为这是使用而不是触发器。

create table Country (
     id int primary key not null identity(1,1)
    ,name varchar(10)
)
go

create table Item (
     id int primary key not null identity(1,1)
    ,country_id int references Country(id)
    ,data varchar(100)
)
go

create view ItemView as
select C.name, I.data
from Item I inner join Country C on I.country_id = C.id
go

create trigger tr_Item_IOI on ItemView
instead of insert as begin

    set nocount on

      -- add the country if it does not exist
    if(not exists (select C.id from Country C inner join inserted I on C.name = I.name))
         insert into Country select distinct name from inserted

      -- insert an item using the country id for the inserted country name
    insert into Item (country_id, data)
    select C.id, I.data
    from Country C inner join inserted I on C.name = I.name

end
go

insert into ItemView values 
     ('USA', '123')
    ,('Canada', '4545')
    ,('Mexico', '4363')
    ,('USA', '3434')
go

select * from ItemView
select * from Country
select * from Item

在此处输入图像描述

于 2012-04-13T00:00:35.333 回答
0

让 INSERT TRIGGER 完成这项工作。

情景一)

插入数据的表有 3 列

CountryID INT NULL,
Country VARCHAR(50) NULL,
SomeData VARCHAR(MAX) NOT NULL

上传者做INSERT INTO MyTable(Country, SameData) VALUES(...)

您的 INSERT TRIGGER 必须

  • 对于inserted表中的每一行
  • 在另一个(引用的)表中找到匹配的 CountryID(外键)
  • UPDATE SET外键匹配的 CountryID
  • UPDATE SET Country = NULL清洁空间

场景 B)

两张桌子

上传者表格

Country VARCHAR(50) NOT NULL,
SomeData VARCHAR(MAX) NOT NULL

目标表

CountryID INT NOT NULL,
SomeData VARCHAR(MAX)

您的 INSERT TRIGGER 必须

  • 对于inserted表中的每一行
  • 使用匹配的外键将其重写到目标表中

还可以尝试使用上述场景INSTEAD OF INSERT TRIGGER(与经典的 AFTER INSERT TRIGGER 相比),因此 Country 列甚至不会写到 DB 中 - 它会即时“转换”为 CountryID。在场景 B 中,上传者的表实际上可能是一个视图(上传者插入到视图中,而不是插入触发器来完成工作)。请参阅以下示例:http: //msdn.microsoft.com/en-us/library/ms175089.aspx

于 2012-04-12T23:20:51.390 回答
-1

我不明白这个问题。您可以拥有一张国家/地区表,并且可以将文本表示用作键,它不必是 ID 号(int、bigint 等)。此表将包含每个国家/地区的一个实例:美国、加拿大、墨西哥。

在您的关系中,您有另一个表,someData其中存储可以包含多个条目,例如 USA。好处是您的国家/地区表可以包含更多关于对象的列(在本例中为国家/地区)。

于 2012-04-12T19:32:46.107 回答