Перебирайте таблицы таблиц для динамического СОЗДАНИЯ структур таблиц - PullRequest
0 голосов
/ 18 января 2019

У меня есть таблица метаданных с четырьмя столбцами Table_N, Column_N, DType & DLength, я пытаюсь перебрать таблицу метаданных и для каждой отдельной таблицы динамически плюнуть оператор CREATE TABLE со всеми его столбцами, типами данных и длиной данных. В основном типичная структура таблицы или определение.

До сих пор я добавил курсор для их обхода и столкнулся с препятствиями с использованием синтаксиса Dynamic SQL, особенно в отношении значений NULL для определенных значений столбца для поля DLength. Например, если тип данных для столбца, скажем, DATE, тогда значение Dlength для этого столбца будет равно NULL. Если я объединю столбец, который имеет VARCHAR для DType и 100 для DLength , то '@DT' + '(' + @ DL + ')' приведет к VARCHAR (100), но с DATE, INT или любые другие подобные типы данных, мне нужен другой подход. Кроме того, не большой поклонник курсора, поэтому, если у вас совершенно другой подход к этому, пожалуйста, не стесняйтесь советовать. Любое предложение высоко ценится. Спасибо!

Имя таблицы: DDC_Loop (пример ниже с метаданными 2 таблиц)

Table_N         Column_N    DType       DLength
--------------------------------------------------------
AUT_C_TABLOG    ORIGINAL    VARCHAR             1
AUT_C_TABLOG    PROTOCOL    VARCHAR             1
AUT_C_TABLOG    TABNAME         VARCHAR            30
ANLA             GEGST          VARCHAR             8
ANLA             GPLAB            DATE             NULL
ANLA             GRBLT          VARCHAR             5
ANLA             GRBND          VARCHAR             5
ANLA             KTOGR          VARCHAR             8
ANLA             LAND1          VARCHAR             3
ANLA             MENGE          NUMERIC           16,3

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Вы можете попытаться создать динамический оператор и выполнить этот оператор. Здесь необходимо нумеровать строки для каждого отдельного имени таблицы, а затем, когда номер строки равен 1, включать CREATE TABLE часть оператора SQL.

-- Table
CREATE TABLE #DDC_Loop (
    Table_N nvarchar(100),         
    Column_N nvarchar(100),    
    DType nvarchar(100),       
    DLength nvarchar(100)
)
INSERT INTO #DDC_Loop
    (Table_N, Column_N, DType, DLength)
VALUES
    ('AUT_C_TABLOG', 'ORIGINAL', 'VARCHAR', '1'),
    ('AUT_C_TABLOG', 'PROTOCOL', 'VARCHAR', '1'),
    ('AUT_C_TABLOG', 'TABNAME',  'VARCHAR', '30'),
    ('ANLA',         'GEGST',    'VARCHAR', '8'),
    ('ANLA',         'GPLAB',    'DATE',    NULL),
    ('ANLA',         'GRBLT',    'VARCHAR', '5'),
    ('ANLA',         'GRBND',    'VARCHAR', '5'),
    ('ANLA',         'KTOGR',    'VARCHAR', '8'),
    ('ANLA',         'LAND1',    'VARCHAR', '3'),
    ('ANLA',         'MENGE',    'NUMERIC', '16,3')

-- Dynamci statement
DECLARE @stm nvarchar(max)
SET @stm = N''
;WITH cte AS (
    SELECT 
        Table_N, 
        Column_N, 
        DType, 
        DLength,
        ROW_NUMBER() OVER (PARTITION BY Table_N ORDER BY Table_N) RN,
        CASE 
            WHEN DLength IS NULL THEN N', ' + Column_N + N' ' + DType
            ELSE N', ' + Column_N + N' ' + DType + N'(' + DLength + N')'
        END ColumnDefinition
    FROM #DDC_Loop
)
SELECT 
    @stm = @stm + 
    CASE 
        WHEN RN = 1 THEN N'); CREATE TABLE ' + Table_N + N'(' + STUFF(ColumnDefinition, 1, 2, N'')
        ELSE ColumnDefinition
    END
FROM cte
ORDER BY Table_N, RN
SET @stm = STUFF(@stm, 1, 3, N'') + SUBSTRING(@stm, 1, 3)

-- Print and execute statement
PRINT @stm
EXEC (@stm)

Сгенерированный оператор:

CREATE TABLE ANLA(GEGST VARCHAR(8), GPLAB DATE, GRBLT VARCHAR(5), GRBND VARCHAR(5), KTOGR VARCHAR(8), LAND1 VARCHAR(3), MENGE NUMERIC(16,3)); 
CREATE TABLE AUT_C_TABLOG(ORIGINAL VARCHAR(1), PROTOCOL VARCHAR(1), TABNAME VARCHAR(30)); 
0 голосов
/ 18 января 2019

С общим табличным выражением, задержкой, опережением, парой выражений падежей и для пути XML вы можете вернуть операторы создания таблицы для всего содержимого таблицы в виде одной длинной строки.

Сначала создайте и заполните образец таблицы ( Пожалуйста, сохраните этот шаг в ваших будущих вопросах)

CREATE TABLE Tables
(
    Table_N sysname,         
    Column_N sysname,    
    DType sysname,
    DLength varchar(5)
);

INSERT INTO Tables (Table_N, Column_N, DType, DLength) VALUES
('AUT_C_TABLOG', 'ORIGINAL', 'VARCHAR', '1'),
('AUT_C_TABLOG', 'PROTOCOL', 'VARCHAR', '1'),
('AUT_C_TABLOG', 'TABNAME',  'VARCHAR', '30'),
('ANLA', 'GEGST', 'VARCHAR', '8'),
('ANLA', 'GPLAB', 'DATE', NULL),
('ANLA', 'GRBLT', 'VARCHAR', '5'),
('ANLA', 'GRBND', 'VARCHAR', '5'),
('ANLA', 'KTOGR', 'VARCHAR', '8'),
('ANLA', 'LAND1', 'VARCHAR', '3'),
('ANLA', 'MENGE', 'NUMERIC', '16,3');

Затем используйте cte, чтобы получить имя таблицы отставания и таблицы опережений (чтобы вы знали, когда добавлять таблицу добавления, а когда - нет):

WITH CTE AS 
(
    SELECT  Table_N, 
            Column_N, 
            DType, 
            DLength, 
            LAG(Table_N) OVER(ORDER BY Table_N) AS PrevTableName,
            LEAD(Table_N) OVER(ORDER BY Table_N) AS NextTableName
    FROM Tables
)

Теперь, используйте несколько выражений в запросе:

SELECT  CASE WHEN PrevTableName IS NULL OR Table_N <> PrevTableName 
            THEN 'CREATE TABLE '+ Table_N +' (' 
            ELSE '' 
        END + Column_N +' '+ DType +
        CASE WHEN DLength IS NULL 
            THEN '' 
            ELSE '('+ DLength +')'
        END +
        CASE WHEN NextTableName IS NULL OR Table_N <> NextTableName 
            THEN '); '
            ELSE ', ' 
        END
FROM CTE
ORDER BY Table_N, Column_N -- Don't forget this order by, it's important!
FOR XML PATH('')

Результаты:

CREATE TABLE ANLA (GEGST VARCHAR(8), GPLAB DATE, GRBLT VARCHAR(5), GRBND VARCHAR(5), KTOGR VARCHAR(8), LAND1 VARCHAR(3), MENGE NUMERIC(16,3)); 
CREATE TABLE AUT_C_TABLOG (ORIGINAL VARCHAR(1), PROTOCOL VARCHAR(1), TABNAME VARCHAR(30)); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...