动态选择列名和前1条记录

时间:2019-04-04 15:39:17

标签: sql sql-server tsql dynamic

我试图根据输出选择表中的前1列值,以了解数据 (即

  SELECT c.name FROM st.Name

此查询检索列名及其数据类型以及它们所在的表。我正在寻找另外一列,以显示该列中排名靠前的1条记录。

SELECT 
st.name 'Table Name', 
c.name 'Column Name', 
t.name 'Data Type'

FROM sys.columns c
INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id 
LEFT OUTER JOIN sys.tables st ON st.object_id = i.object_id 

我一直在尝试使用动态sql,但是由于它应该将表名作为字符串放在单引号中,因此它无法工作;当我尝试避免这种情况时,它仅显示声明的变量。 任何想法都非常感谢。谢谢

2 个答案:

答案 0 :(得分:2)

因此,这种工作方式基本上是创建一堆选择,例如:

SELECT 'dbo' AS [Schema Name]
     , 'Table1' AS [Table Name]
     , 'Id' AS [Column Name]
     , 'bigint' AS [Data Type]
     , (SELECT TOP 1 CONVERT(NVARCHAR(MAX), Id) FROM [dbo].[Table1]) AS [Top 1 Value] 

UNION ALL

-- Another table

将值转换为NVARCHAR(MAX),因为联合中的列类型必须匹配,我猜这是最好的选择。

在这里:

DECLARE @query NVARCHAR(MAX) = ''
SELECT @Query += 
'SELECT ' + '''' + sch.name + '''' + ' AS [Schema Name],' + CHAR(13)+CHAR(10)
          + '''' + st.name  + '''' + ' AS [Table Name],' + CHAR(13)+CHAR(10)
          + '''' + c.name   + '''' + ' AS [Column Name],' + CHAR(13)+CHAR(10)
          + '''' + t.name   + '''' + ' AS [Data Type],' + CHAR(13)+CHAR(10)
          + '(SELECT TOP 1 CONVERT(NVARCHAR(MAX), ' + c.name + ') FROM ' + QUOTENAME(sch.name) + '.' + QUOTENAME(st.name) + ') AS [Top 1 Value] ' + CHAR(13)+CHAR(10)
          + 'UNION ALL'+CHAR(13)+CHAR(10)
FROM sys.columns c
JOIN sys.types t ON c.user_type_id = t.user_type_id
JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id 
JOIN sys.tables st ON st.object_id = i.object_id 
JOIN sys.schemas sch ON sch.schema_id = st.schema_id

-- Get rid of trailing UNION ALL
SET @Query = LEFT(@Query, LEN(@Query) - LEN('UNION ALLxx'))

PRINT @query
EXEC sp_executesql @query

考虑先运行TOP 10或类似的软件,以确保其产生正确的结果。

答案 1 :(得分:0)

您可以在d sql中使用while循环

-

--drop table #temp

SELECT 
    CONCAT(s.name,'.',st.name) 'Table Name', 
    c.name 'Column Name', 
    t.name 'Data Type',
    CAST(null AS datetime) as IND,
    cast('' AS varchar(max)) data
    INTO #temp
FROM sys.columns c
INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id 
INNER JOIN sys.tables st ON st.object_id = i.object_id
INNER JOIN sys.schemas s ON s.schema_id = st.schema_id



declare 
@TableName varchar(255),
@ColumnName Varchar(255),
@sql varchar(max)

WHILE (SELECT count(*) FROM #temp where IND is null) > 0
begin

        SELECT TOP 1 
            @TableName = [Table Name]
            ,@ColumnName = [Column Name]
        FROM #temp
        WHERE IND IS NULL

        SET @sql = 
        'update  #temp 
         set data  = (SELECT top 1 [' + @ColumnName + '] from ' + @TableName + '),
         IND = getdate()
         where [Table Name] = ''' + @TableName + ''' and [Column Name] = ''' +  @ColumnName + ''''

        exec(@sql)
end


SELECT * 
FROM #temp