SQL Server: добавьте «Тип» в каждый столбец таблицы - PullRequest
0 голосов
/ 02 сентября 2018

У меня есть таблица DemoTable в SQL Server. И у него есть эти столбцы:

Column1, Column2, Column3

Я хочу запросить таблицу

select * from DemoTable

но в результатах запроса я хочу объединить Type_ со всеми именами столбцов, доступными в DemoTable.

Таким образом, в результате этого запроса должны отображаться столбцы

Type_Column1, Type_Column2, Type_Column3

Есть ли какая-либо функция или способ ее достижения?

Примечание: количество столбцов N, а не только 3, только для того, чтобы переименовывать только их вручную.

Ответы [ 4 ]

0 голосов
/ 03 сентября 2018

Некоторые общие замечания:

  • При динамическом присвоении имен столбцам набора результатов в любом случае потребуется динамический 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 голосов
/ 02 сентября 2018

Если проблема как вы говорите:

После объединения всех таблиц существует много повторяющихся имен столбцов

тогда типичное решение - НЕ использовать *. Так что вместо этого:

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 ...
0 голосов
/ 02 сентября 2018

Вот один из способов автоматизации вашей задачи с использованием динамического 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);
0 голосов
/ 02 сентября 2018

Вы можете использовать следующий запрос для добавления «Типа» в каждый столбец таблицы:

SELECT Column1 AS Type_Column1, Column2 AS Type_Column2, Column3 AS Type_Column3
FROM DemoTable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...