2013-01-09 1 views
0

테이블 집합에 대해 테이블 ​​당 1:1보기를 자동으로 만드는 방법을 찾고 있습니다. 뷰가 필요한 테이블이 많으므로 테이블을 수동으로 만드는 데 많은 시간이 걸릴 수 있습니다.은 여러 테이블에 대한보기를 자동으로 만듭니다.

완벽한 시나리오는 한 번에 주어진 각 테이블에 대해 create view 개의 쿼리를 만드는 쿼리입니다.

+0

지금까지 해보신 것은 무엇입니까? [sys.tables] (http://msdn.microsoft.com/en-us/library/ms187406(v=sql.100) .aspx) 및 [sys.columns] (http://msdn.microsoft .com/ko-us/library/ms176106 (v = sql.100) .aspx) 필요한 이름을 얻으십시오. 그게 도움이 되니? – Pondlife

+0

예. 나는 뷰를 생성하기 위해이 생성 된 동적 SQL을 살펴 보았습니다. 좀 더 "우아한"솔루션을 원했습니다! – Nico

+0

"우아한"이란 무엇을 의미합니까? 어떤 솔루션을 선택하든 테이블과 컬럼 이름을 검색하고 CREATE VIEW 문을 빌드해야합니다. 따라서 유일한 질문은 TSQL에서 또는 외부 코드 (SMO를 사용했을 때)를 사용하는 것입니까? – Pondlife

답변

1

이것은 현재 데이터베이스의 트릭을 수행해야합니다. 여전히 동적 인 SQL이지만 뷰가 이미 존재하는지 확인하지 않습니다. WHERE 절을 커서 쿼리에 추가하여 테이블 (WHERE t.name = '...' 또는 WHERE t.name IN ('...','....'))을 제한 할 수 있습니다. 내가 아는

DECLARE @TableName sysname 
DECLARE @ColumnCount INT 
DECLARE @ColumnID INT 
DECLARE @SelectColumn NVARCHAR(500) 
DECLARE @sql NVARCHAR(max) = '' 

DECLARE QUERYINFO CURSOR FOR 
    SELECT 
     t.name AS TableName, 
     ccount.ColumnCount, 
     c.column_id AS ColumnID, 
     CASE WHEN c.column_id <> ccount.ColumnCount 
       THEN c.name + ', ' 
      ELSE c.name 
      END AS SelectColumn 
    FROM sys.tables t 
    INNER JOIN sys.columns c ON t.object_id=c.object_id 
    INNER JOIN (
     SELECT object_id,COUNT(*) AS ColumnCount 
     FROM sys.columns 
     GROUP BY object_id 
    ) ccount ON t.object_id = ccount.object_id 
    ORDER BY t.Name,c.column_id 

OPEN QUERYINFO 
FETCH NEXT FROM QUERYINFO INTO @TableName,@ColumnCount,@ColumnID,@SelectColumn 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    IF @ColumnID = 1 
    BEGIN 
     SET @sql = 'CREATE VIEW v_' + @TableName + ' AS SELECT ' + @SelectColumn 
    END 
    ELSE 
    BEGIN 
     SET @sql = @sql + @SelectColumn 
    END 

    IF @ColumnID = @ColumnCount 
    BEGIN 
     SET @sql = @sql + ' FROM ' + @TableName 
     EXEC sys.sp_executesql @sql 
     SET @sql = '' 
    END 

    FETCH NEXT FROM QUERYINFO INTO @TableName,@ColumnCount,@ColumnID,@SelectColumn 
END 

CLOSE QUERYINFO 
DEALLOCATE QUERYINFO 
+0

ColumnID가 순차적이지 않을 수 있으므로 IF \ @ColumnID = \ @ColumnCount 절이 예상대로 작동하지 않을 수 있습니다. 예를 들어 열을 삭제 한 후 (마지막 항목 제외) ID의 번호가 다시 지정되지 않습니다. – Rashack

0

이 조금 일자하지만 당신은 프로 시저 또는 커서를 사용하지 않고 문자열로 재귀 CTE와 sys.columns 및 sys.tables에서 함께 열을 임시 테이블을 사용하여 다음 뷰를 만들 수있다 . 다음은 그 예입니다. 이것은 하나의 object_id 만 선택하지만 db의 모든 테이블에 대해 실행할 수 있습니다. 유일한 문제는 100 열보다 큰 표가있는 경우 일 수 있습니다. CTE의 기본 깊이는 100 개의 재귀 조인이라고 생각합니다.

SELECT t.name AS TableName 
     , ccount.ROW_COUNT 
     , c.column_id AS ROW_RANK 
     , c.name as COL 

INTO #VT_TEMP 

FROM sys.tables t INNER JOIN sys.columns c 
ON t.object_id=c.object_id 

INNER JOIN ( SELECT object_id 
        , COUNT(*) AS ROW_COUNT 
       FROM sys.columns 
       GROUP BY object_id 
    ) ccount 
ON t.object_id = ccount.object_id 
WHERE t.OBJECT_ID = 245575913 
ORDER BY t.Name, c.COLUMN_ID 
; 



WITH MYVIEW_CTE (T_NAME, R_COUNT, R_RANK, TXT) 

AS 
    (
    SELECT TABLENAME 
     , ROW_COUNT 
     , ROW_RANK 
     , CAST(COL AS VARCHAR(MAX)) 

    FROM #VT_TEMP 
    WHERE ROW_RANK = 1 

    UNION ALL 

    SELECT V.TABLENAME 
      , V.ROW_COUNT 
      , V.ROW_RANK 
      , CAST(TXT + ', ' + V.COL AS VARCHAR(MAX)) 


    FROM #VT_TEMP V INNER JOIN MYVIEW_CTE C 
    ON V.TABLENAME = T_NAME 
    AND V.ROW_RANK = R_RANK + 1 
) 

SELECT CC.T_NAME 
     ,CC.TXT 
     , 'CREATE VIEW V_' + CC.T_NAME + ' AS SELECT ' + CC.TXT + ' FROM dbo.' + CC.T_NAME + ' ;' as DDL_View 
FROM MYVIEW_CTE CC INNER JOIN (

SELECT T_NAME, MAX(R_RANK) AS MX_CNT 
FROM MYVIEW_CTE C 
GROUP BY T_NAME 
) SC 
ON CC.T_NAME = SC.T_NAME 
AND CC.R_RANK = SC.MX_CNT 
관련 문제