列出表中具有一个记录的关联值的列

时间:2014-02-21 16:01:37

标签: sql sql-server

我正在构建一个查询,该查询应列出表中的所有列以及每个列名的数据样本。例如,如果我有一个名为'person'的表,其中包含'first','last'和'age'列,我需要将其列为如下所示:

table_name    column_name    column_value
person        person_id      443
person        first          john
person        last           smith
person        age            48

此查询的目标是实际列出任何给定表中的所有列 - 我有这个工作。我希望在第三列(column_value)中列出一个数据值,以便我可以针对后端检查应用程序的前端,并确保我实际处理的是正确的列。

这个表可能有数百或数千条记录,但我只是试图拉出一条匹配的记录。我在任何给定表中使用的平均表列是200+,所以我不能手动执行此操作。

以下是我用来从表中提取所有列的查询:

SELECT table_name
       , COLUMN_NAME
       , '' AS column_value
FROM   information_schema.COLUMNS
WHERE  TABLE_NAME LIKE '%person%'
ORDER BY TABLE_NAME

此查询返回以下结果(通知column_value为空):

table_name    column_name    column_value
person        person_id
person        first
person        last
person        age

我将使用唯一的主键来识别要从中提取的单个人记录 - 这将确保我没有重复的列名(例如,每次拉人时重复的person_id / first / last / age)。 )

问题是,如何将其转换为列列表以及“column_value”列中特定选定记录的值?

更新

只是为了澄清,我基本上试图改变这种类型的查询&输出:

SELECT * FROM person WHERE person_id = 443;

** outputs this:
person_id    first    last    age
443          john     smith   48

进入这个:

table_name    column_name    column_value
person        person_id      443
person        first          john
person        last           smith
person        age            48

3 个答案:

答案 0 :(得分:1)

你可以试试这样的事情

DECLARE @SchemaName sysname
DECLARE @TableName sysname
DECLARE @Colname sysname
DECLARE @SQL_Template nvarchar(max)
DECLARE @SQL nvarchar(max)

SET @SchemaName = 'Sales' 
SET @TableName = 'Customer' 

CREATE TABLE ##Results(Colname sysname, colvalue varchar(256))

SET @SQL_Template  = 'INSERT INTO ##Results(Colname,colvalue ) SELECT top 1 ''@Colname '' as Colname,'
                   + ' CONVERT(nvarchar(256),@Colname) AS ColValue'
                   + ' FROM ['+@SchemaName+'].['+@TableName+']'


DECLARE COL_CURSOR CURSOR STATIC FOR
SELECT c.name
FROM  sys.schemas s
 JOIN sys.tables t ON t.schema_id = s.schema_id
 JOIN  sys.columns c ON c.object_id = t.object_id
WHERE s.name = 'Sales' AND t.name = 'Customer'
OPEN COL_CURSOR 
FETCH NEXT FROM COL_CURSOR INTO @Colname
WHILE @@FETCH_STATUS =0
BEGIN
    SET @SQL = REPLACE(@SQL_Template,'@ColName',@ColName)
    PRINT @SQL
    EXEC sp_executesql  @SQL
FETCH NEXT FROM COL_CURSOR INTO @Colname
END
CLOSE COL_CURSOR 
DEALLOCATE COL_CURSOR 
SELECT * FROM ##Results
DROP TABLE ##Results

答案 1 :(得分:0)

我创建了这个过程,它将Table Name作为Parameter并返回您要求的信息。

CREATE PROCEDURE usp_GetTableFormat_And_SampleDate
@TableName NVARCHAR(128)
AS
BEGIN
 SET NOCOUNT ON;

DECLARE @ColsCasted NVARCHAR(MAX);
DECLARE @Cols NVARCHAR(MAX);

SELECT @TableName = t.name
     , @ColsCasted = STUFF(( SELECT ', CAST(' + QUOTENAME(sc.name) + ' AS NVARCHAR(1000)) AS ' + QUOTENAME(sc.name)
                         FROM sys.tables st INNER JOIN sys.columns sc 
                         ON st.object_id = sc.object_id
                         WHERE st.name = @TableName
                         AND st.object_id = t.object_id
                         FOR XML PATH(''),TYPE)
                         .value('.','NVARCHAR(MAX)'),1 ,2 ,'')
FROM sys.tables t
WHERE t.name = @TableName
GROUP BY t.name, t.object_id

SELECT @TableName = t.name
     , @Cols = STUFF(( SELECT ', ' + QUOTENAME(sc.name) 
                 FROM sys.tables st INNER JOIN sys.columns sc 
                 ON st.object_id = sc.object_id
                 WHERE st.name = @TableName
                 AND st.object_id = t.object_id
                 FOR XML PATH(''),TYPE)
                 .value('.','NVARCHAR(MAX)'),1 ,2 ,'')
FROM sys.tables t
WHERE t.name = @TableName
GROUP BY t.name, t.object_id;

DECLARE @Sql NVARCHAR(MAX);

SET @Sql =

N'WITH CTE AS 
 (
 SELECT * FROM (
SELECT TOP 1 ' + @ColsCasted + N'
FROM ' + QUOTENAME(@TableName)  + N') Q 
  UNPIVOT ( VALS for N IN (' + @Cols + '))up
)
SELECT  TableName
      , ColName AS ColumnName
      , VALS AS SampleData 
FROM CTE C INNER JOIN  
(SELECT sc.Name AS ColName, st.Name AS TableName FROM sys.tables st INNER JOIN sys.columns sc 
ON st.object_id = sc.object_id WHERE st.name =  '''+ @TableName +  N''' ) Q2 
ON C.N = Q2.ColName'

EXECUTE sp_executesql @Sql

END

<强>测试

我的数据库中有一个名为'Department'的表

EXECUTE usp_GetTableFormat_And_SampleDate 'Department'

结果集

╔════════════╦════════════╦════════════╗
║ TableName  ║ ColumnName ║ SampleData ║
╠════════════╬════════════╬════════════╣
║ Department ║ DeptID     ║ 1          ║
║ Department ║ Department ║ HR         ║
╚════════════╩════════════╩════════════╝

答案 2 :(得分:0)

如果只需要几个表,那么你可以将它捆绑到一个联合查询中

CREATE PROC sp_person_values (@PersonID  int)
AS 
BEGIN 
    SELECT 'person_id' As ColumnName, CONVERT(varchar(256),person_id) As ColumnValue FROM person WHERE person_id = @PersonID
    UNION ALL
    SELECT 'first' As ColumnName, CONVERT(varchar(256),first) As ColumnValue FROM person WHERE person_id = @PersonID
    UNION ALL
    SELECT 'last' As ColumnName, CONVERT(varchar(256),last) As ColumnValue FROM person WHERE person_id = @PersonID
    UNION ALL
    SELECT 'age' As ColumnName, CONVERT(varchar(256),age) As ColumnValue FROM person WHERE person_id = @PersonID
END