2015-05-09 50 views
2

如何避免在两个不同的表中有两个具有相同名称的字段取相同的值?
例如,我有表的客户:如何避免在两个不同的表中具有相同名称的两个字段在sql中取相同的值?

cust_id telephone country 
    1  03458902  UK 
    2  05868915  DE 

而在另一方面,我有表卖家:

seller_id telephone country 
    1   07854264  GR 
    2   03458902  ES 

在这个例子中,该电话号码是唯一的,所以应该不会与卖家和顾客是同一电话。 应该有插入命令的警告:

insert into seller values(2,'03458902','ES') 

我知道应该有类似如下:

create trigger .... before insert on seller 

但我不是很熟悉的名词。
我在MySQL中找到了一个例子。但是我不知道如何将它从MySQL代码更改SQL代码:

DROP TRIGGER IF EXISTS `unique_telephone_seller`; 
DELIMITER // 
CREATE TRIGGER `unique_telephone_seller` BEFORE INSERT ON `seller` 
    FOR EACH ROW BEGIN 
    DECLARE c INT; 
     SELECT COUNT(*) INTO c FROM customer WHERE telephone = NEW.telephone; 
     IF (c > 0) THEN 
      -- abort insert, because foo.username should be NOT NUL 
      SET NEW.telephone = NUL; 
     END IF; 
END 

后来编辑:

因为每个人都在怀疑我的问题,让我解释一下为什么我有2个表。 我必须建立一个电信数据库。客户可以预付和后付费的SIM卡。因此,我有一个客户名单(ID,姓名,地址等),一张预付费SIM卡(client_id,phone_no等)以及一张用于后付费SIM卡((client_id,phone_no等))的表格。
有两种类型的SIM卡,或者是同一类型的倍数,这就是为什么我将SIM卡分成2张表格(SIM卡有其他参数取决于类型)
因此,在插入表格之前不要有重复的phone_no要验证该号码是否在其他表

问候//克里斯蒂娜

+5

我觉得你的数据模型有问题。为什么卖家不能成为客户? –

+0

这只是一个例子。当然,卖家可以成为客户。但是,与客户和卖家解释它更简单。 – Cristina

+1

同意@GordonLinoff。如果你的电话号码或其他什么都是唯一的,那么这是你的主键,不应该在两个表中。应该有一个表的电话号码和其他位(客户或卖家ID和国家)挂在那。 – LoztInSpace

回答

0

你可以让一个程序INSERT前检查:

CREATE PROCEDURE dbo.Sample_Procedure 
    @seller_Id int, 
    @telephone VARCHAR(8), 
    @country CHAR(2) 
AS 
    IF EXISTS (SELECT cust_id FROM customer WHERE telephone = @telephone) 
     SELECT 'This phone number exists in customer table.' 
    ELSE 
     INSERT INTO seller VALUES(@seller_Id, @telephone, @country) 
RETURN 0 
+0

这不起作用。事务隔离意味着插入电话的事务A不能检查事务B是否也在执行它,直到完成为止。它只在重复值已被提交时才有效。 – LoztInSpace

+0

True @LoztInSpace。但只要事务在调用这个过程之前就已经完成了,就没有问题。 – sqluser

+0

是的,但将您的系统转变为可接受的单用户系统?也许,也许不是。我的偏好是不要将这些限制放在特别限制之中,特别是当前或未来的开发人员/产品经理未考虑甚至认定的限制。如果你只是做对了,那么没有人会关心隐藏在实施内容中的任何限制。 – LoztInSpace

0

使用INSTEAD OF而不是要求您处理插入逻辑。使用FOR允许您发出回滚,并让插入逻辑定期发生。

要使整个块失效,请确保将其包含在事务中。

CREATE TRIGGER trigger_table_phone 
ON dbo.customer_phone 
FOR INSERT,UPDATE 
AS 
BEGIN 
    IF EXISTS(SELECT 1 FROM dbo.seller_phone p INNER JOIN inserted i ON p.phone = i.phone) 
    BEGIN 
     RAISERROR('A phone number exists in seller phone and cannot be inserted',16,1) 
    END 
END 
+0

这不会一直工作。它只在重复值已经提交时才起作用,并且不会阻止在两个单独的事务中同时插入相同的值。 – LoztInSpace

+0

虽然我同意这应该是一个单独的表,但打开查询以提交未提交的内容将允许您查看这些记录。运营商必须决定什么是可以接受的 - 但这是我甚至没有提到的。谢谢。 – user4882995

相关问题