2015-07-02 87 views
1

我想找出一个更好,更有效的方式来编写下面的脚本。任何人都可以想出一种方法来实现相同的目标而不使用游标?寻找替代游标

“用户”可能会在table1中出现多次,但只能在table2中存在一次。

TABLE1

|Name |Access | 
------------------- 
User1 |N  | 
User1 |N  | 
User1 |Y  | 

TABLE2

|Name |Access | 
------------------- 
User1 |   | 
User2 |   | 
User3 |   | 

代码:

DECLARE @Name VarChar(50), @Access VarChar(1) 

DECLARE TestCursor CURSOR FOR 
    SELECT Name, Access FROM Table1 ORDER BY Obj ASC 

OPEN TestCursor 
FETCH NEXT FROM TestCursor INTO @Name, @Access 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    UPDATE table2 
    SET Table2.Access = CASE 
          WHEN Table1.Access = 'Y' THEN Table1.Access 
         ELSE Table2.Access END 
    FROM table1 
    JOIN table2 ON table1.name = table2.name 

    FETCH NEXT FROM TestCursor INTO @Name, @Access 
END 

CLOSE TestCursor 
DEALLOCATE TestCursor 
+0

不表1真的列表user1的3倍?如果是的话,user1应该访问哪些内容?和以前的答案存在这样的问题...如:http://stackoverflow.com/questions/224732/sql-update-from-one-table-to-another-based-on-a-id-match否需要重新发明轮子。 – xQbert

回答

1
UPDATE t2 
SET  access = t1.access 
FROM (
     SELECT name, MAX(CASE access WHEN 'Y' THEN 'Y' END) access 
     FROM table1 
     GROUP BY 
       name 
     ) t1 
JOIN table2 t2 
ON  t2.name = t1.name 
     AND t1.access = 'Y' 
WHERE EXISTS 
     (
     SELECT t1.access 
     EXCEPT 
     SELECT t2.access 
     ) 
1

瓦我的理解是,只有当来自table1的最新(由max obj列定义)访问权限为“Y”时,才想更新Table2的访问列。

尝试了这一点:

UPDATE @Table2 
SET Access = CA.Access 
FROM @Table2 AS T2 
CROSS APPLY (
       SELECT TOP 1 Access 
       FROM @Table1 AS T1 
       WHERE  T1.Name = T2.Name 
         AND T1.Access = 'Y' 
       ORDER BY Obj DESC 
      ) CA