从不同的表中检索列名?
Posted
技术标签:
【中文标题】从不同的表中检索列名?【英文标题】:Retrieve column names from a different table? 【发布时间】:2009-02-05 21:25:48 【问题描述】:我有一个“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
诀窍在于,对于不同类型的机器,“值”列 MEAN 有不同的含义。所以我们有一个“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。
谢谢!
【问题讨论】:
【参考方案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
【讨论】:
【参考方案2】:动态 sql 选项将是(作为查询而不是写入 proc):
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 调用它时...从而消除了必须动态化的一些性能痛苦。
【讨论】:
【参考方案3】:创建一个表,存储该单独查询类型的每个值的标题名称。
然后,创建一个存储过程并使用动态 SQL 填写从该表中提取的列名。
【讨论】:
【参考方案4】:由于您无法更改数据模型,我建议将表示代码放入应用程序的表示层。有一个表格,根据请求的结果为您提供要使用的列标题,然后从那里开始。
【讨论】:
以上是关于从不同的表中检索列名?的主要内容,如果未能解决你的问题,请参考以下文章