czwartek, 30 grudnia 2010

UPDATE CTE

Ostatnio, jeden z moich znajomych miał do napisania skrypt, który do istniejącej tabeli doda kolumnę ID i uzupełni ją danymi (ponumeruje wiersze). Pierwsza myśl jaka mi przyszła do głowy to wykorzystanie funkcji ROW_NUMBER() do ponumerowania wierszy. Przykładowa tabelka, już z dodaną kolumną ID poniżej.


USE TEMPDB;
GO

CREATE TABLE T
(
      ID INT NULL,
      VAL VARCHAR(10)
);

INSERT INTO T (ID, VAL)
VALUES (NULL, 'A')
      , (NULL, 'B')
      , (NULL, 'C');

SELECT *
FROM T; 























Mamy więc już tabelkę z kolumną ID, ale jeszcze wartość w kolumnie to NULL. Jak ponumerować wiersze? O tym poniżej.

W pierwszej kolejności przygotowujemy sobie CTE, w którym dodajemy do tabelki nową kolumnę (u mnie to jest TEMPID), która powstaje z wykorzystania funkcji ROW_NUMBER(). Mając już tak przygotowane CTE robimy prosty UPDATE, który przepisze nam wartość z TEMPID do naszej kolumny ID do tabelki T. Dziwne jest to, że UPDATE robimy na CTE, a nie bezpośrednio na tabeli. Mimo to w magiczny sposób kolumna ID w naszej tabli zostaje zmieniona.

WITH TCTE
AS
(
      SELECT ROW_NUMBER() OVER (ORDER BY VAL ASC) AS TEMPID
            , ID
            , VAL
      FROM T
)
UPDATE TCTE
SET ID = TEMPID;

SELECT *
FROM T; 


















Poniżej jeszcze skrypt w całości.

USE TEMPDB;
GO

CREATE TABLE T
(
      ID INT NULL,
      VAL VARCHAR(10)
);

INSERT INTO T (ID, VAL)
VALUES (NULL, 'A')
      , (NULL, 'B')
      , (NULL, 'C');

SELECT *
FROM T;

WITH TCTE
AS
(
      SELECT ROW_NUMBER() OVER (ORDER BY VAL ASC) AS TEMPID
            , ID
            , VAL
      FROM T
)
UPDATE TCTE
SET ID = TEMPID;

SELECT *
FROM T;

DROP TABLE T;