2009-09-10 98 views
1

哦,太棒了#1,我求你...... 我需要做到以下几点:SQL子选择在更新

CREATE UNIQUE INDEX用户名对emp(用户名) - 啧!

UPDATE Emp SET 
UserName = Left(FirstName,1)+LastName 

WHERE不存在具有该用户名的雇员已经存在。

+1

你真的想更新整套用户名吗?这是一个危险的想法。 – HLGEM 2009-09-10 19:45:54

+0

这仍然允许重复...我猜你试图避免重复,不只是重置UserNames,其中没有现有的是与提议的新值相同? – 2009-09-10 19:56:58

+0

不,我想要做的是为用户分配一个用户名。 我已将问题简化为单个语句,以便有人可以回答,因为我无法弄清楚语法。 – 2009-09-10 20:00:23

回答

1

这将仍然允许重复......但如果你想你说的话, 试试这个(你说什么):

UPDATE Emp SET 
    UserName = Left(FirstName,1) + LastName 
Where Not Exists (Select * From Emp 
        Where UserName = Left(FirstName,1) + LastName) 

我猜想,但是,你要设法避免重复,而不是重置用户名,其中现有的用户名与建议的新值不相同。如果是的话,你应该在username列增加一个唯一索引,但首先,运行以下命令:

UPDATE Emp SET 
    UserName = Left(FirstName,1) + LastName 
Where Not Exists 
      (Select * From Emp 
       Where UserName = Left(FirstName,1) + LastName) 
    And Not Exists 
      (Select * From Emp 
       Group By Left(FirstName,1) + LastName 
       Having Count(*) > 1) 

这将重置可以重置,而无需创建重复的所有用户名。 (它不会消除现有的Dupes)。如果在此之后没有欺骗,则可以应用索引。

+0

我认为你的子查询没有与外部查询中的值进行比较。 – 2009-09-10 19:50:39

+0

我想我正在寻找的是内部select如何在外部更新语句中引用EmpID的语法。 – 2009-09-10 20:09:08

+0

下面是引用外部选择... 更新Ë 组用户名的语法= ... 从的EmpË 其中不存在(SELECT * FROM的Emp其中username =左(e.FirstName,1)+ E .LastName)... – 2009-09-10 21:45:40

4

是的,因为你不读更深入的用户名真的应该是唯一的,我会确保where子句中有其他东西,因为这将是一个激烈的查询。

您可能会考虑编写一个函数来为您添加一些其他唯一性或ID到结尾(如果存在的话)(Count(*)其中用户名如用户名)。

UPDATE Emp SET 
UserName = Left(FirstName,1)+LastName 
WHERE 
UserName not in (Select UserName From Emp Where UserName = Left(FirstName,1) + LastName) 
+0

假设SQL数据库是TSQL – Highstead 2009-09-10 19:42:49

+1

,并且假设您在更新时不会导致重复,即如果您有John Smith和James Smith,则他们在更新期间都会变成JSmith。 – 2009-09-10 19:48:26

+0

我认为你的子查询没有检查语句外部的值。 – 2009-09-10 19:52:01

4

我会把一个唯一索引上的用户名和用途:

UPDATE IGNORE Emp SET UserName = Left(FirstName,1)+LastName 

如果你的数据库支持;)

+1

+1上的独特索引 - 你可以在你的应用程序中进行各种验证,但它只会从DBA或具有写入权限的人员的一个错误中破坏数据。 – Mayo 2009-09-10 19:46:18

+0

SQL Server是否支持IGNORE子句? 你是什么意思的笑脸? 这是否意味着“太糟糕了,你无法做到这一点!”? – 2009-09-10 20:02:18

+0

Mysql支持它。我不知道是否有其他数据库。 – Pomyk 2009-09-10 21:58:20

1

首先,您的用户名字段应该有一个唯一索引。如果你不这样做,那么你的数据就有可能在某个人更新的时候没有使用你的小更新语句。当前的代码建议没有给你一个如何处理用户名设置的例子,如果使用现有的用户名,你想要做什么?这应该是你的过程的一部分。用户需要用户名。

只是为了显示这里是一种处理递增用户名的方式,直到你找到一个不存在的用户名。这个例子是一个插入不是更新,但我认为你可以用它作为开始的地方。通过使用这种方法(这是一次插入一条记录),没有人会用重复的用户名进入系统,并且如果存在完全匹配,则不会抛出错误,它只是继续寻找下一个匹配项。

CREATE PROC [dbo].[ins_MyUserTable] 
(
@userID int, 
@Login varchar(255) 
) 

As 

DECLARE 

@ValidateUserName varchar(50), 
@NewUserName varchar(50), 
@CheckUserName varchar(50), 
@Holding int 

-- Get User Name (first letter of first name + last name) 
SELECT @NewUserName = @Login 
SET @Holding = 0 

-- Examine User Name (must be unique) 
SELECT @ValidateUserName = 1 

WHILE @ValidateUserName = 1 
    BEGIN 
    -- Check for Login 
    SELECT @CheckUserName = (SELECT TOP 1 login FROM MyUserTable WHERE login = @NewUserName) 

    IF @CheckUserName = @NewUserName 
     BEGIN 
        SELECT @Holding = @Holding + 1 
     SELECT @NewUserName = @Login + Convert(varchar(2), @Holding) 
     END 
    ELSE 
     BEGIN 
     SELECT @ValidateUserName = 0 
     END 
    END 
    -- Insert into MyUserTable 
    INSERT INTO MyUserTable 
     ([user_id], login) 
    VALUES 
     (@userID, @NewUserName) 
+0

我想要做的是为用户分配一个用户名。 我希望它是名字的第一个字母,后面跟着姓。 如果员工已经拥有该用户名,我不会抛出错误。 但我不想让这个例子复杂化,人们不理解它。 所以我将这个例子简化为1个语句。 这就是我所做的。 – 2009-09-10 19:58:54