SQL Server:向表中的每一列添加“类型”

问题描述 投票:1回答:4

我在SQL Server中有一个表DemoTable。它有以下列:

Column1, Column2, Column3

我想查询表格

select * from DemoTable

但在查询结果中,我想将Type_连接到DemoTable中可用的所有列名。

因此,此查询的结果应该是显示列

Type_Column1, Type_Column2, Type_Column3

是否有任何功能或任何方法来实现这一目标?

注意:N个列不仅仅是3个,只是手动重命名。

sql sql-server tsql
4个回答
1
投票

以下是使用动态SQL自动执行任务的一种方法:

use MY_DATABASE;
go
--here you specify all your parameters,  names should be self-explanatory
declare @sql varchar(1000) = 'select ',
        @tableName varchar(100) = 'DemoTable',
        @prefix varchar(10) = 'Type_';

select @sql = @sql + name + ' as ' + @prefix + name + ',' from sys.columns
where object_name(object_id) = @tableName;

set @sql = left(@sql, len(@sql) - 1) + ' from ' + @tableName;

exec(@sql);

3
投票

如果问题如你所说:

加入所有表后,有许多重复的列名

那么典型的解决方案是不使用*。所以不是这样的:

SELECT *
FROM A
JOIN B ON ...
JOIN C ON ...

...您应该考虑使用自定义列集,这是正常和推荐的方法,如下例所示:

SELECT A.Column1, A.Column2, B.Column3, C.Column4, C.Column5
FROM A
JOIN B ON ...
JOIN C ON ...

1
投票

一些一般性评论:

  • 动态命名结果集的列在任何情况下都需要动态SQL。没办法......
  • 在大多数情况下,命名列来传递额外信息是一个非常糟糕的主意。
  • 我知道在SELECT * FROM ...中处理星号并且仍能完全控制列名称和类型的唯一方法是XML。

试试这个:

SELECT TOP 10 * 
FROM sys.objects 
FOR XML RAW, ROOT('TableDef'),ELEMENTS, XMLSCHEMA,TYPE

这将返回第10行sys.objects。结果是XML,其中行遵循XML模式定义。

可以(但肯定不是性能最佳)动态创建完全内联查询。结果将是一个EAV列表,其中包含您需要的一切。

WITH PrepareForXml(QueryAsXml) AS
(
SELECT
    (
    SELECT TOP 10 * 
    FROM sys.objects 
    FOR XML RAW, ROOT('TableDef'),ELEMENTS, XMLSCHEMA,TYPE
    )
)
,AllRows AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RowIndex
          ,rw.query('.') theRowXml
    FROM PrepareForXml
    CROSS APPLY QueryAsXml.nodes('TableDef/*:row') A(rw)
)
SELECT RowIndex
      ,B.ColumnName
      ,B.ColumnValue

      ,COALESCE(
      (SELECT QueryAsXml.value('declare namespace xsd="http://www.w3.org/2001/XMLSchema";
                                 (TableDef
                                 /xsd:schema
                                 /xsd:element
                                 /xsd:complexType
                                 /xsd:sequence
                                 /xsd:element[@name=sql:column("ColumnName")]
                                 /@type )[1]','nvarchar(max)') 
        FROM PrepareForXml)
      ,(SELECT QueryAsXml.value('declare namespace xsd="http://www.w3.org/2001/XMLSchema";
                                 (TableDef
                                 /xsd:schema
                                 /xsd:element
                                 /xsd:complexType
                                 /xsd:sequence
                                 /xsd:element[@name=sql:column("ColumnName")]
                                 /xsd:simpleType
                                 /xsd:restriction
                                 /@base)[1]','nvarchar(max)') 
        FROM PrepareForXml)
        ) AS ColumnType
FROM AllRows
CROSS APPLY theRowXml.nodes('*:row/*') A(col)
CROSS APPLY (SELECT col.value('local-name(.)','nvarchar(max)') ColumnName
                   ,col.value('(./text())[1]','nvarchar(max)') ColumnValue ) B;

这是结果集的开头:

RowIndex    ColumnName  ColumnValue ColumnType
1           name        sysrscols   sqltypes:nvarchar
1           object_id   3           sqltypes:int
1           schema_id   4           sqltypes:int
[...many more...]

我不知道你究竟需要什么,但它可能足以按原样导出XML。它就是那里的一切......

更新:我没有仔细阅读......

你想说明一个事实,即结果集的列名必须是唯一的才能继续这个...

上述方法无法解决此问题。抱歉。

我不会立即删除它...可能有一些提示你可以摆脱这个......


0
投票

您可以使用以下查询将“类型”添加到表中的每个列:

SELECT Column1 AS Type_Column1, Column2 AS Type_Column2, Column3 AS Type_Column3
FROM DemoTable
© www.soinside.com 2019 - 2024. All rights reserved.