Spis treści:

Kategoria:SQL Server


Jak wygenerować tymczasową tabelę na dane innej tabeli

Dzisiejszy problem jest następujący: zamierzamy przeprowadzić na wybranej tabeli takie operacje, które wymagają tymczasowego przechowania danych w innym miejscu. Może to być spowodowane względami bezpieczeństwa, koniecznością mocnej przebudowy tabeli, ale też innymi, być może zaskakującymi potrzebami.

Skrypt generujący tabelę na bazie innej

Przyjrzyjmy się teraz skryptowi, który realizuje nasze zadanie. Zaprezentowany jest on na poniższym listingu:

CREATE FUNCTION dbo.GetTempTable(@tabName nvarchar(128))
RETURNS nvarchar(MAXAS
BEGIN
DECLARE @q nvarchar(MAX) = 'CREATE TABLE #' + @tabName + CHAR(13) + '('CHAR(13)
DECLARE @col nvarchar(128)
DECLARE @type nvarchar(128)
DECLARE @maxlength varchar(8)
DECLARE @precision varchar(8)
DECLARE @scale varchar(8)
DECLARE cur CURSOR FOR
SELECT C.name, TP.name, C.max_length, C.[precision], C.scale
FROM sys.tables T
JOIN sys.columnsON T.[object_id] = C.[object_id]
JOIN sys.types TP ON TP.user_type_id = C.user_type_id
WHERE T.name = @tabName
OPEN cur
FETCH NEXT FROM cur INTO @col, @type, @maxlength, @precision, @scale
WHILE @@FETCH_STATUS=0
BEGIN
  SET @q = @q + ' ' + @col + ' ' + @type
  
  --Dodaj argumenty varchar i nvarchar
  --oraz varbinary
  IF @type = 'varchar' OR @type = 'nvarchar' OR @type = 'varbinary'
  BEGIN
    IF @maxlength = -1
      SET @q = @q + '(MAX)'
    ELSE
      SET @q = @q + '(' + @maxlength + ')'
  END
  
  --Dodaj argumenty char i nchar
  IF @type = 'char' OR @type = 'nchar'
    SET @q = @q + '(' + @maxlength + ')'

  IF @type = 'decimal' OR @type = 'numeric'
    SET @q = @q + '(' + @precision + ', '+ @scale + ')'

  FETCH NEXT FROM cur INTO @col, @type, @maxlength, @precision, @scale
  IF @@FETCH_STATUS=0
    SET @q = @q + ','CHAR(13)
END
CLOSE cur
DEALLOCATE cur
SET @q = @q + CHAR(13) + ')'
RETURN @q
END

Zaprezentowana funkcja generuje skrypt, który pozwala stworzyć tabelę wskazaną parametrem, ale z przedrostkiem #, czyli tabelę tymczasową. Tabela tymczasowa nie posiada kluczy, indeksów. Jej celem jest tylko i wyłącznie przechowanie danych.

Popatrzmy jeszcze, jak to działa. Przykładowy skrypt pokazany jest na poniższym listingu:

--Tworzymy przykładową tabelę
CREATE TABLE T1
(
  ID int,
  Val numeric(6,2),
  Num decimal,
  Num2 decimal(10),
  Txt varchar(200),
  TxtM varchar(MAX),
  Bin varbinary(2000),
  BinM varbinary(MAX)
)
GO

--Wywołanie funkcji
SELECT dbo.GetTempTable('T1')

Wynikiem działania powyższego skryptu będzie następujący łańcuch znaków:

CREATE TABLE #T1
(
  ID int,
  Val numeric(6, 2),
  Num decimal(18, 0),
  Num2 decimal(10, 0),
  Txt varchar(200),
  TxtM varchar(MAX),
  Bin varbinary(2000),
  BinM varbinary(MAX)
)

Co zrobimy z takim skryptem, zależy już tylko od nas samych. Deklaracja w przypadku pól typu numeric i decimal może się nieco różnić (jest to deklaracja pełna), ale jest całkowicie zgodna z oryginałem.

Kategoria:SQL Server

, 2013-12-20

Brak komentarzy - bądź pierwszy

Dodaj komentarz
Wyślij
Ostatnie komentarze
Dzieki za te informacje. były kluczowe
Dobrze wyjaśnione, dzięki !
a z innej strony - co gdybym ciąg znaków chciał mieć rozbity nie na wiersze a na kolumny? Czyli ciąg ABCD: 1. kolumna: A, 2. kolumna: B, 3. kolumna: C, 4 kolumna: D?
Ciekawy artykuł.
Czy można za pomocą EF wysłać swoje zapytanie?
Czy lepiej do tego użyć ADO.net i DataTable?