2009-02-05 67 views
0

我有一个“datadump”表,有一堆混合的性能相关的数据。 喜欢的东西:从不同的表中检索列名?

MachID TestDate MachType Value1 Value2 ... 
00001 01/01/09 Server 15  48  
00001 01/02/09 Server 16  99  
19999 01/01/09 Switch 32  4.9880 
19999 01/02/09 Switch 32  5.8109 

的诀窍是“价值”列意味着不同类型的机器不同的东西。所以我们有一个“xRef”表,如下所示:

MachType  Column Description 
Server   Value1 Users Connected 
Server   Value2 % CPU _total 
Switch   Value1 Number of Ports 
Switch   Value2 packets/ms 
... 

我知道,奇怪的结构,但我没有做到,也无法改变它。

我想以某种方式“内部连接”这些,所以我可以根据数据类型查询适当的列标题。事情是这样的服务器:

MachID TestDate MachType Users Connected  % CPU _total Total RAM 
00001 01/01/09 Server 15     48    4096 
00001 01/02/09 Server 16     99    4096 

这对于开关:

MachID TestDate MachType Number of Ports packets/ms Total Cumulative kb 
19999 01/01/09 Switch 32    4.9880  1024547 
19999 01/02/09 Switch 32    5.8109  1029450 

有没有办法做到这一点没有做单独的硬编码查询每种类型的?

注意:我只需要一次查询对象的一个​​类型。最有可能的是,如果有帮助,我只会查看单个MachID的特定日期之间的所有结果。这是MS SQL 2000.

谢谢!

回答

0

创建一个表,存储该单个查询类型的每个值的标题名称。

然后,创建一个存储过程并使用动态SQL来填充从该表中绘制的列名称。

0

由于您无法更改数据模型,我建议将表示代码放入应用程序的表示层。有一张表格,根据请求的结果为您提供要使用的列标题,并从那里开始。

1

这将一起完成它们 - 如果您希望它们全部分离,您可以根据需要进行修改。

DECLARE @template AS varchar(max) 
DECLARE @sql AS varchar(max) 
DECLARE @column_list AS varchar(max) 
SELECT @column_list = COALESCE(@column_list + ', ', '') 
     + QUOTENAME([Description]) 
FROM xRef 

SET @template = '; 
WITH up 
      AS (
       SELECT MachID 
         ,TestDate 
         ,MachType 
         ,[COLUMN] 
         ,[Value] 
       FROM  datadump UNPIVOT ([Value] FOR [Column] IN ([Value1], [Value2])) AS unpvt 
      ) 
      ,ready AS (
    SELECT machID 
      ,TestDate 
      ,up.MachType 
      ,[Description] 
      ,up.[Value] 
    FROM up 
    INNER JOIN xRef 
      ON xRef.machType = up.MachType 
       AND xRef.[Column] = up.[Column] 
) 
SELECT * FROM ready 
PIVOT (SUM([Value]) FOR [Description] IN ({@column_list})) AS pvt 
' 

machID TestDate    MachType Users Connected       % CPU _total       Number of Ports       packets/ms 
------ ----------------------- -------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- 
00001 2009-01-01 00:00:00.000 Server 15.000000000000000      48.000000000000000      NULL         NULL 
00001 2009-01-02 00:00:00.000 Server 16.000000000000000      99.000000000000000      NULL         NULL 
19999 2009-01-01 00:00:00.000 Switch NULL         NULL         32.000000000000000      4.988000000000000 
19999 2009-01-02 00:00:00.000 Switch NULL         NULL         32.000000000000000      5.810900000000000 
1

动态SQL选项会(写出为,而不是做成一个进程查询):

declare @machtype varchar(40) --stored proc parameter? 
set @machtype = 'Switch' --or 'Server' 

declare @sql nvarchar(4000) 

set @sql = 'select 
    MachID, 
    TestDate, 
    MachType, 
    Value1 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value1') + ''', 
    Value2 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value2') + ''', 
    Value3 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value3') + ''' 
from 
    dbo.datadump 
where 
    machtype = ''' + @machtype + '''' 

exec sp_executesql @sql 

如果发现实在太丑陋的人,那么你包装的逻辑得到在功能列名会收拾一下吧:

create function dbo.ColNameForDataDump(
    @machtype varchar(40), 
    @column varchar(40) 
) 
RETURNS varchar(40) 
as 
begin 

    declare @col_desc varchar(40) 
    select 
     @col_desc = [description] 
    from 
     dbo.xref 
    where 
     machtype = @machtype 
     and [column] = @column 

    return @col_desc 
end 

然后动态SQL看起来更像:

declare @machtype varchar(40) --stored proc parameter? 
set @machtype = 'Switch' --or 'Server' 

declare @sql nvarchar(4000) 

set @sql = 'select 
    MachID, 
    TestDate, 
    MachType, 
    Value1 as ''' + dbo.ColNameForDataDump(@machtype, 'Value1') + ''', 
    Value2 as ''' + dbo.ColNameForDataDump(@machtype, 'Value2') + ''', 
    Value3 as ''' + dbo.ColNameForDataDump(@machtype, 'Value3') + ''' 
from 
    dbo.datadump 
where 
    machtype = ''' + @machtype + '''' 

exec sp_executesql @sql 

最后一个关于上面的代码的传递点/评论:你提到你在SQL Server 2000上,所以确保你必须编写一些动态sql来将其定义为nvarchar并使用sp_executesql来调用它。因此否定了一些不得不变得动态的表现痛苦。