2015-07-02 77 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