我正在构建一个查询,该查询应列出表中的所有列以及每个列名的数据样本。例如,如果我有一个名为'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
答案 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