我正在使用SQL Server 2008的项目。我们将一些数据加载到大量表中。对于每个表,都会创建几个视图。 第一个视图,我们称之为标准视图,只列出表中的所有列。
第二个视图,我们称之为自定义视图,只列出表中特定的选定列。由于业务需求,需要此视图。所选列是手工挑选的,和RENAMED 等
现在我想通过自动提取两个视图和表中的所有列如何相互关联来记录这一点。 这就是问题出现的地方。
我使用以下SQL来制作列表:
/* Run this for the DATABASE you want info on. */
/* The first table lists all Tables and columns. */
with ListOfTableColumns as (
select
TheTables.name as 'TableName'
,TheColumns.name as 'ColumnName'
,TheColumns.column_id as 'ColumnNumber'
from sys.tables as TheTables /* Find tables */
join sys.columns as TheColumns /* Find columns from tables */
on TheColumns.object_id = TheTables.object_id
),
/* The second table contains all Custom views and columns. */
ListOfCustomViewColumns as (
SELECT
object_name(d.object_id) as ViewName,
c.name AS ViewColumn,
isnull(type_name(c.system_type_id), t.name) AS DateType,
object_name(d.referenced_major_id) as TableName,
tablecols.name AS TableColumn
FROM
sys.views v
JOIN sys.columns c ON c.object_id = v.object_id
LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id
JOIN sys.sql_dependencies d ON d.object_id = v.object_id
AND c.column_id = d.referenced_minor_id
JOIN sys.columns tablecols ON d.referenced_major_id = tablecols.object_id
AND tablecols.column_id = d.referenced_minor_id
AND tablecols.column_id = c.column_id
where v.schema_id = (select schema_id from sys.schemas where name = 'LZSDS') /* We only want the Custom views. */
),
/* The third table contains all Standard views and columns. */
ListOfStandardViewColumns as (
SELECT
object_name(d.object_id) as ViewName,
c.name AS ViewColumn,
isnull(type_name(c.system_type_id), t.name) AS DateType,
object_name(d.referenced_major_id) as TableName,
tablecols.name AS TableColumn
FROM
sys.views v
JOIN sys.columns c ON c.object_id = v.object_id
LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id
JOIN sys.sql_dependencies d ON d.object_id = v.object_id
AND c.column_id = d.referenced_minor_id
JOIN sys.columns tablecols ON d.referenced_major_id = tablecols.object_id
AND tablecols.column_id = d.referenced_minor_id
AND tablecols.column_id = c.column_id
where v.schema_id = (select schema_id from sys.schemas where name = 'LZSVW') /* We only want the Custom views. */
)
/* Create the actual final list of Tables and Views. */
select
ListOfTableColumns.TableName as 'Table_name'
,ListOfTableColumns.ColumnName as 'Table_column_name'
,ListOfTableColumns.ColumnNumber as 'Table_column_number'
,ListOfStandardViewColumns.ViewColumn as 'Standard_view_column_name'
,ListOfStandardViewColumns.ViewName as 'Standard_view_name'
,ListOfCustomViewColumns.ViewColumn as 'Custom_view_column_name'
,ListOfCustomViewColumns.ViewName as 'Custom_view_name'
from ListOfTableColumns
left join ListOfStandardViewColumns
on ListOfTableColumns.TableName = ListOfStandardViewColumns.TableName
and ListOfTableColumns.ColumnName = ListOfStandardViewColumns.TableColumn
left join ListOfCustomViewColumns
on ListOfTableColumns.TableName = ListOfCustomViewColumns.TableName
and ListOfTableColumns.ColumnName = ListOfCustomViewColumns.TableColumn
order by ListOfTableColumns.TableName, ListOfTableColumns.ColumnNumber
只要自定义视图包含所有列,上面的代码就可以很好地匹配列。一旦他们中的一些人被选中不参与观点,他们就会在摘录中出现错误。
问题图片可以在这里看到:http://pasteboard.co/2yqRNOj1.png
如何从sys.tables或INFORMATION_SCHEMA中提取可以正确匹配列的提取?
如果您想要一些示例代码来设置问题的表,我在下面提供了它。 (您可能需要更改某些模式名称等以适合您的安装。)
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[LZS].[TBDLZLT000_TESTTABLE1]') AND type in (N'U'))
DROP TABLE [LZS].[TBDLZLT000_TESTTABLE1]
GO
CREATE TABLE [LZS].[TBDLZLT000_TESTTABLE1](
[DWH_DATE] [datetime] NOT NULL,
[NUMERIC1] [decimal](3, 0) NOT NULL,
[NUMERIC2] [decimal](3, 0) NULL,
[NUMERIC3] [decimal](3, 0) NULL,
[VARCHAR1] [varchar](3) NOT NULL,
[VARCHAR2] [varchar](3) NULL,
[VARCHAR3] [varchar](3) NULL,
[UPDATE_TIMESTAMP] [datetime] NOT NULL,
CONSTRAINT [PKDLZLT000] PRIMARY KEY CLUSTERED
(
[DWH_DATE] ASC,
[NUMERIC1] ASC,
[VARCHAR1] ASC,
[UPDATE_TIMESTAMP] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Create Standard View
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[LZSVW].[STANDARD_TEST_TABLE_VIEW]'))
DROP VIEW [LZSVW].[STANDARD_TEST_TABLE_VIEW]
GO
CREATE VIEW [LZSVW].[STANDARD_TEST_TABLE_VIEW] as select
*
from LZS.TBDLZLT000_TESTTABLE1
;
GO
-- Create Custom View
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[LZSDS].[CUSTOM_TEST_TABLE_VIEW]'))
DROP VIEW [LZSDS].[CUSTOM_TEST_TABLE_VIEW]
GO
CREATE VIEW [LZSDS].[CUSTOM_TEST_TABLE_VIEW] as select
DWH_DATE
,NUMERIC1 AS NUM1
,NUMERIC3 AS NUM3
,VARCHAR1 AS VC1
,VARCHAR3 AS VC3
,UPDATE_TIMESTAMP
from LZS.TBDLZLT000_TESTTABLE1
where DWH_DATE = (SELECT MAX(DWH_DATE) FROM LZS.TBDLZLT000_TESTTABLE1)
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[LZS].[TBDLZLT002_TESTTABLE2]') AND type in (N'U'))
DROP TABLE [LZS].[TBDLZLT002_TESTTABLE2]
GO
CREATE TABLE [LZS].[TBDLZLT002_TESTTABLE2](
[DWH_DATE] [datetime] NOT NULL,
[NUMERIC1] [decimal](3, 0) NOT NULL,
[NUMERIC2] [decimal](3, 0) NULL,
[NUMERIC3] [decimal](3, 0) NULL,
[VARCHAR1] [varchar](3) NOT NULL,
[VARCHAR2] [varchar](3) NULL,
[VARCHAR3] [varchar](3) NULL,
[UPDATE_TIMESTAMP] [datetime] NOT NULL,
CONSTRAINT [PKDLZLT002] PRIMARY KEY CLUSTERED
(
[DWH_DATE] ASC,
[NUMERIC1] ASC,
[VARCHAR1] ASC,
[UPDATE_TIMESTAMP] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Create Standard View
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[LZSVW].[STANDARD_TEST_TABLE2_VIEW]'))
DROP VIEW [LZSVW].[STANDARD_TEST_TABLE2_VIEW]
GO
CREATE VIEW [LZSVW].[STANDARD_TEST_TABLE2_VIEW] as select
*
from LZS.TBDLZLT002_TESTTABLE2
;
GO
-- Create Custom View
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[LZSDS].[CUSTOM_TEST_TABLE2_VIEW]'))
DROP VIEW [LZSDS].[CUSTOM_TEST_TABLE2_VIEW]
GO
CREATE VIEW [LZSDS].[CUSTOM_TEST_TABLE2_VIEW] as select
DWH_DATE
,NUMERIC1 AS NUM1
,NUMERIC2 AS NUM2
,NUMERIC3 AS NUM3
,VARCHAR1 AS VC1
,VARCHAR2 AS VC2
,VARCHAR3 AS VC3
,UPDATE_TIMESTAMP
from LZS.TBDLZLT002_TESTTABLE2
where DWH_DATE = (SELECT MAX(DWH_DATE) FROM LZS.TBDLZLT002_TESTTABLE2)
GO
答案 0 :(得分:0)
您可以使用INFORMATION_SCHEMA.VIEW_COLUMN_USAGE,如下所示(根据您的示例数据):
;WITH TableColumnsLZS as
(
SELECT
s.name as 'SchemaName'
,t.name as 'TableName'
,c.name as 'ColumnName'
,c.column_id as 'ColumnNumber'
FROM sys.tables as t
INNER JOIN sys.columns as c ON c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = 'LZS'
)
, StandardViewColumnsLZSVW AS
(
SELECT *
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE AS UsedColumns
WHERE UsedColumns.VIEW_SCHEMA = 'LZSVW'
),
CustomViewColumnsLZSDS AS
(
SELECT *
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE AS UsedColumns
WHERE UsedColumns.VIEW_SCHEMA = 'LZSDS'
)
SELECT LZS.TableName Table_name,
LZS.ColumnName Table_column_name,
LZS.ColumnNumber Table_column_number,
LZSVW.COLUMN_NAME Standard_view_column_name,
LZSVW.VIEW_NAME Standard_view_name,
LZSDS.COLUMN_NAME Custom_view_column_name,
LZSDS.VIEW_NAME Custom_view_name
FROM TableColumnsLZS LZS
LEFT JOIN StandardViewColumnsLZSVW LZSVW ON LZS.SchemaName = LZSVW.TABLE_SCHEMA AND LZS.TableName = LZSVW.TABLE_NAME AND LZS.ColumnName = LZSVW.COLUMN_NAME
LEFT JOIN CustomViewColumnsLZSDS LZSDS ON LZS.SchemaName = LZSDS.TABLE_SCHEMA AND LZS.TableName = LZSDS.TABLE_NAME AND LZS.ColumnName = LZSDS.COLUMN_NAME
返回:
编辑:
INFORMATION_SCHEMA.VIEW_COLUMN_USAGE中的COLUMN_NAME获取列的真实姓名,而不是别名。当视图中的列数不等于表中的列数时,尝试与INFORMATION_SCHEMA.COLUMNS一起加入也不起作用,因为ordinal_position是从表级保留的。
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS tc
INNER JOIN INFORMATION_SCHEMA.VIEW_COLUMN_USAGE vu on vu.table_schema = tc.table_schema
and vu.table_name = tc.table_name
and vu.column_name = tc.column_name
INNER JOIN INFORMATION_SCHEMA.COLUMNS vc on vc.table_schema = vu.view_schema
and vc.table_name = vu.view_name
and tc.ordinal_position = vc.ordinal_position
WHERE vu.VIEW_SCHEMA = 'LZSDS'
但这有效:
;WITH TableColumnsLZS as
(
SELECT
s.name as 'SchemaName'
,t.name as 'TableName'
,c.name as 'ColumnName'
,c.column_id as 'ColumnNumber'
FROM sys.tables as t
INNER JOIN sys.columns as c ON c.object_id = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = 'LZS'
)
, StandardViewColumnsLZSVW AS
(
SELECT *
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE AS UsedColumns
WHERE UsedColumns.VIEW_SCHEMA = 'LZSVW'
),
OrdinalPositionCTE
AS
(
SELECT vu.*,
ROW_NUMBER() OVER(PARTITION BY vu.table_name ORDER BY ordinal_position) ordinal_position
FROM INFORMATION_SCHEMA.COLUMNS tc
INNER JOIN INFORMATION_SCHEMA.VIEW_COLUMN_USAGE vu on vu.table_schema = tc.table_schema
and vu.table_name = tc.table_name
and vu.column_name = tc.column_name
WHERE vu.VIEW_SCHEMA = 'LZSDS'
),
CustomViewColumnsLZSDS
AS
(
SELECT op.*, vc.COLUMN_NAME Alias
FROM OrdinalPositionCTE op
INNER JOIN INFORMATION_SCHEMA.COLUMNS vc on vc.table_schema = op.view_schema
and vc.table_name = op.view_name
and op.ordinal_position = vc.ordinal_position
)
SELECT LZS.TableName Table_name,
LZS.ColumnName Table_column_name,
LZS.ColumnNumber Table_column_number,
LZSVW.COLUMN_NAME Standard_view_column_name,
LZSVW.VIEW_NAME Standard_view_name,
LZSDS.Alias Custom_view_column_name,
LZSDS.VIEW_NAME Custom_view_name
FROM TableColumnsLZS LZS
LEFT JOIN StandardViewColumnsLZSVW LZSVW ON LZS.SchemaName = LZSVW.TABLE_SCHEMA AND LZS.TableName = LZSVW.TABLE_NAME AND LZS.ColumnName = LZSVW.COLUMN_NAME
LEFT JOIN CustomViewColumnsLZSDS LZSDS ON LZS.SchemaName = LZSDS.TABLE_SCHEMA AND LZS.TableName = LZSDS.TABLE_NAME AND LZS.ColumnName = LZSDS.COLUMN_NAME