2016-06-22 24 views
3

私は約200のテーブルを持っています。これらのすべてのテーブルからviewを作成します。すべてのテーブル名をハードコードし、ビュー定義でUNION ALLを実行することが非効率的だと感じます。 sysobjectsテーブルのテーブル名を使用してSQL Serverビューを作成します。

は、代わりに私は次のように sysobjectsテーブルからテーブル名を取得する予定です

Select name from sysobjects where name like 'Warehouse_Inventory%' 

どのように私はこれらのテーブル名を使用して、それのうちviewを作成することができますか?

注:10個のコラムのみを選択しています。表に列がない場合は、NULLを表示します。あなたの代わりに他のSYSビューのsys.sysojectsを使いたい理由

+0

これらのテーブル内のすべての列が同じでない限り、これらのテーブルの結合を行うのは難しいでしょう。これには動的SQLが必要です。あなたが探しているUNIONではなくJOINの場合は、結合する列をハードコードする必要があります。 – Sam

+0

私はすべてのテーブルに存在する列だけを選択しています。それらが存在しない場合は、NULLを表示しています。 – turbo88

+0

どのようにすべてのテーブルにすべてのユニオンを行うことができますか?彼らは列の同じデータ型と同じnoを持っていますか? –

答えて

0

このクエリはあなたを助けるかもしれない...

SELECT 'CREATE VIEW VIEW_NAME AS' 
    UNION ALL 
    SELECT 'SELECT * FROM ['+NAME+'] 
    UNION ALL' FROM SYS.TABLES where name like 'Warehouse_Inventory%' 
+1

これは彼が見ることができるものですが、列リストがすべてのテーブルで同じではないため、選択したすべてのステートメントを実行するとエラーが発生します。 – Sam

+0

このクエリは、最後の行にUNION ALLを出力します。 – turbo88

+0

これは1回限りのアクティビティである場合は、手動でUNION ALLを削除するか、XMLまたは@Variableを使用して1行にマージして最後のUNION ALLを削除します。この場合、どちらが単純か........: ) –

0

は私はわかりません。また、なぜ今あなたがテーブル名で検索したいと思うすべてのテーブルを結合したいのですか?私はおそらく200テーブルを持っている場合は、結果を保持するためにテーブルと一時テーブルにカーソルをお勧めしますあなたが実際に本当に組合を介してそれをしたい場合は、ここにすべての方法です...

あなたが望む10の列のリストを作成します。次に、クエリを実行します。 sys.typesとsys.columnsを使って動的に行うことができる、またはすべてがNVARCHAR(???)であることを確認するために、キャスト/変換関数を調整して追加する必要があるかもしれません。下に移動して前進する。

DECLARE @ListOfColumns AS TABLE (ColumnName VARCHAR(100)) 
INSERT INTO @ListOfColumns (ColumnName) VALUES ('col1'),('col2'),('col3') 

DECLARE @SQLStatement NVARCHAR(MAX) 

;WITH cteColumnsTableCross AS (
    SELECT 
     SchemaName = s.name 
     ,t.schema_id 
     ,TableName = t.name 
     ,l.ColumnName 
    FROm 
     @ListOfColumns l 
     CROSS JOIN sys.tables t 
     INNER JOIN sys.schemas s 
     ON t.schema_id = s.schema_id 
) 


, cteColumns AS (
    SELECT 
     x.SchemaName 
     ,x.TableName 
     ,x.ColumnName 
     ,ColumnExists = IIF(c.name IS NOT NULL,1,0) 
     ,RowNum = ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY x.TableName DESC) 
     --you can add data type by getting from sys.columns and sys.types if desired 
    FROM 
     cteColumnsTableCross x 
     LEFT JOIN sys.tables t 
     ON x.TableName = t.name 
     AND x.schema_id = t.schema_id 
     LEFT JOIN sys.columns c 
     ON t.object_id = c.object_id 
     AND x.ColumnName = c.name 
) 

, cteSelectStatements AS (
    SELECT 
     TableName = t.name 
     ,TableSelect = 'SELECT TableName = ''' + t.name + ''', ' + 

      STUFF(
      (SELECT ', ' + c.ColumnName + ' = ' + IIF(c.ColumnExists = 0,'NULL',c.ColumnName) 
      FROM 
       cteColumns c 
      WHERE t.name = c.Tablename 
      FOR XML PATH('')) 
      ,1,1,'') 

      + ' FROM ' + t.name + 

      IIF((ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY t.name DESC)) > 1,' UNION ALL ','') 
    FROM 
     sys.tables t 
) 

SELECT @SQLStatement = STUFF(
     (SELECT ' ' + TableSelect 
     FROM 
      cteSelectStatements 
     ORDER BY 
      TableName 
     FOR XML PATH('')) 

     ,1,1,'') 

PRINT @SQLStatement 
--EXECUTE @SQLStatement 
関連する問題