简体   繁体   中英

SQL Server : add 'Type' to every column in table

I have a table DemoTable in SQL Server. And it has these columns:

Column1, Column2, Column3

I want to query the table

select * from DemoTable

but in query results I want to concatenate Type_ to all the column names available in DemoTable .

So the result of this query should be showing columns

Type_Column1, Type_Column2, Type_Column3

Is there any function or any way to achieve this?

Note: there are N number of columns not only 3 just to rename only these manually.

If the problem is as you say:

After joining all the tables , there are many duplicate column names

then the typical solution is to NOT use * . So instead of this:

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

... you should consider using a custom column set, which is the normal and recommended way to do this, as in the following example:

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

Here's one way to automate your task using dynamic 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);

Some general remarks:

  • Naming your result set's columns dynamically will demand for dynamic SQL in any case. No way around...
  • Naming columns to carry extra information is - in most cases - a very bad idea.
  • the only way I know to deal with the asterisk in a SELECT * FROM ... and still get full control over the columns names and types is XML.

Try this:

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

This will return the 10 first rows of sys.objects . The result is an XML, where the rows follow an XML schema definition.

It is possible (but sure not the best in performance) to create a fully inlined query dynamically. The result will be an EAV list carrying everything you need.

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;

This is the beginning of the result-set:

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

I don't know what you need actually, but it might be enough to export the XML as is . It's everything in there...

UPDATE: I did not read carefully enough...

You want to trick out the fact, that a result set's column names must be unique in order to continue with this...

The approach above will not solve this issue. Sorry.

I won't delete this immediately... Might be there are some hints you can get out of this...

You can use the following query to add 'Type' to every column in table:

SELECT Column1 AS Type_Column1, Column2 AS Type_Column2, Column3 AS Type_Column3
FROM DemoTable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM