0

1:1テーブルの束に対して、テーブルごとにビューを自動的に作成する方法を探しています。ビューが必要なテーブルがたくさんあるので、手動で作成するには時間がかかります。

完璧なシナリオは、create view指定された各テーブルのクエリを一度に作成するクエリです。

4

2 に答える 2

2

これにより、現在のデータベースのトリックが実行されます。まだ動的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
于 2013-01-09T15:53:19.847 に答える
0

これは少し古いことはわかっていますが、再帰的な CTE を持つ一時テーブルを使用して、sys.columns と sys.tables の列をつなぎ合わせ、プロシージャやカーソルを使用せずにビューを構築できます。ここに例があります。これは 1 つの object_id のみを選択しますが、データベース内のすべてのテーブルに対して実行できます。唯一の問題は、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
于 2015-12-03T16:35:00.617 に答える