从SQL中的另一个表中获取列名

时间:2018-01-16 13:05:39

标签: sql sql-server tsql

我有两个表,一个用于保存实际数据,另一个用于列的人类可读名称。

按如下方式查询保存数据的表。

SELECT 
       [H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E]
      ,[H8319D956-2223-41DC-AE91-B504832B8665]
      ,[H05E82ED3-517B-4545-A44E-1BDC2126A3AD]
      ,[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E]
FROM [Database].[dbo].[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]

另外,我有一个'meta'表,其中包含列的实际名称和表本身。

Name                                    DisplayName Table                                       DisplayTable
[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E] [ID]        [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]   [Datatable]
[H8319D956-2223-41DC-AE91-B504832B8665] [Name]      [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]   [Datatable]
[H05E82ED3-517B-4545-A44E-1BDC2126A3AD] [City]      [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]   [Datatable]
[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E] [Country]   [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]   [Datatable]

我正在寻找一种方法来替换我怀疑是唯一标识符的方法,其中包含来自另一个表的人类可读名称。我有多个这些表,共有200多个列,它们的长度和宽度不断扩大(添加了列)。

4 个答案:

答案 0 :(得分:0)

我建议创建一个带有select的表副本,将列名称映射到它们的显示名称。唯一的挑战是创建一系列200选择并执行它们。视图的工作方式相同,但是如果要创建索引,则这将是一个挑战。一切都取决于表的大小以及必须刷新的频率。

您可以使用SELECT对元组和sys.tables,sys.columns和sys.schemas的组合创建系列,使用引号和+将查询连接到执行SELECT INTO的单行。您将其输出到名为@Query的内存表中。然后循环遍历@Query并在动态SQL中逐行执行。

下面是你应该加入元表的sys.tables,sys.columns和sys.schemas的连接(这将有助于验证列名以发现错误)

SELECT 
s.name AS schema_name,
t.name AS table_name, 
c.name AS column_name
    FROM sys.tables t JOIN sys.columns c ON c.object_id = t.object_id JOIN sys.schemas s ON t.schema_id = s.schema_id 

答案 1 :(得分:0)

以下代码演示了一种交换列名的方法。可以修改它以生成用于创建存储过程或视图的语句,而不是生成select查询。

-- Sample data.
create table Metadata ( MetadataId Int Identity,
  TableName VarChar(16), ColumnName VarChar(16), DisplayName VarChar(16) );
insert into Metadata ( TableName, ColumnName, DisplayName ) values
  ( 'Samples', '001', 'ShoeSize' ), ( 'Samples', '042', 'TowelLocation' ),
  ( 'Widgets', 'BR549', 'RingTwo' );
select * from Metadata;

create table Samples ( SampleId Int Identity,
  [001] VarChar(5), [042] VarChar(64) );
insert into Samples ( [001], [042] ) values
  ( '5EEE', 'Left shoulder.' ), ( '14', 'Front hall closet.' );
select * from Samples;

-- Build a query.
declare @TableName as sysname = 'Samples';
declare @ColumnList as NVarChar(2048) = N'';
select @ColumnList = Stuff(
    ( select N',' + QuoteName( M.DisplayName ) + N'=' + QuoteName( M.ColumnName )  
     from sys.columns as C inner join
    Metadata as M on M.TableName = @TableName and M.ColumnName = C.name
  where object_id = Object_Id( @TableName )
  order by column_id for XML path(''), type).value('.[1]', 'VarChar(max)' ),
    1, 1, '' );
declare @Query as NVarChar(4000) = N'select ' + @ColumnList + N' from ' + QuoteName( @TableName );

-- Try it on for size.
select @Query as Query;
execute sp_executesql @statement = @Query;

-- Houseclean.
drop table Samples;
drop table Metadata;

答案 2 :(得分:0)

现在据我了解你的问题,你需要根据Meta表中的数据,将表和列的名称从唯一标识符表格替换为人类可读表格。

现在,首先创建一个表,其列和表名需要更改

--Table whose column name and Table name needs to be changed
CREATE TABLE [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]
(
[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E] VARCHAR(100),
[H8319D956-2223-41DC-AE91-B504832B8665] VARCHAR(100),
[H05E82ED3-517B-4545-A44E-1BDC2126A3AD] VARCHAR(100),
[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E]  VARCHAR(100)
)

--Meta Table 

CREATE TABLE Meta
(
Name VARCHAR(100),
DisplayName VARCHAR(100),
[Table] VARCHAR(100),
DisplayTable VARCHAR(100)
)


INSERT INTO Meta VALUES ('[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E]','[ID]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]')
INSERT INTO Meta VALUES ('[H8319D956-2223-41DC-AE91-B504832B8665]','[Name]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]')
INSERT INTO Meta VALUES ('[H05E82ED3-517B-4545-A44E-1BDC2126A3AD]','[City]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]')
INSERT INTO Meta VALUES ('[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E]','[Country]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]')

现在使用sp_rename过程更改SQL Server中的列名,因此我们需要创建一个将在Meta表上创建的脚本,并以sp_rename格式提供输出。以下示例将明确

--Required Script
SELECT *,'EXEC sp_rename '''+ [Table] + '.' + Name + '''' + ',''' + DisplayName + '''' + ',' + '''COLUMN' + '''' AS Rename_Script FROM Meta

此脚本的输出将包含一列“Rename_Script”,在运行时将改变[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]中列的名称,如您在示例中所述。

EXEC sp_rename '[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA].[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E]','[ID]','COLUMN'
EXEC sp_rename '[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA].[H8319D956-2223-41DC-AE91-B504832B8665]','[Name]','COLUMN'
EXEC sp_rename '[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA].[H05E82ED3-517B-4545-A44E-1BDC2126A3AD]','[City]','COLUMN'
EXEC sp_rename '[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA].[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E]','[Country]','COLUMN'

同样,您需要创建一个用于更改表名称的脚本。 如果您遇到任何问题,请告知我们。

答案 3 :(得分:0)

    IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
    CREATE TABLE #t(Name VARCHAR(255),DisplayName VARCHAR(255),[Table] VARCHAR(255),DisplayTable VARCHAR(255))
    INSERT INTO #t(Name,DisplayName,[Table],DisplayTable) 
    SELECT '[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E]','[ID]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]' UNION ALL 
    SELECT '[H8319D956-2223-41DC-AE91-B504832B8665]','[Name]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]' UNION ALL 
    SELECT '[H05E82ED3-517B-4545-A44E-1BDC2126A3AD]','[City]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]' UNION ALL 
    SELECT '[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E]','[Country]','[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]','[Datatable]'

    DECLARE @sql VARCHAR(max),@tablename VARCHAR(255)
    SET @tablename='[DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]'
    SELECT @sql=ISNULL(@sql+',','')+'t.'+t.Name+' AS '+t.DisplayName
    FROM #t AS t WHERE t.[Table]=@tablename
    SET @sql='SELECT '+CHAR(13)+@sql +CHAR(13)+'FROM '+@tablename
    PRINT @sql
    'EXEC(@sql)
SELECT 
t.[H08CEC38C-281B-4C28-90DE-EEEC1D3C4D2E] AS [ID],t.[H8319D956-2223-41DC-AE91-B504832B8665] AS [Name],t.[H05E82ED3-517B-4545-A44E-1BDC2126A3AD] AS [City],t.[H519574FD-EFC4-4BFB-8BC9-447FF61E0C0E] AS [Country]
FROM [DIM4DE53E67-85C8-4274-B5ED-5F3526314DEA]