Одним из возможных подходов является генерация динамического оператора с использованием UNPIVOT
. Если столбцы имеют разные типы данных, используйте CONVERT
:
Введите:
CREATE TABLE Data (
ColumnVarchar varchar(100),
ColumnDateTime datetime,
ColumnInt int
)
INSERT INTO Data
(ColumnVarchar, ColumnDateTime, ColumnInt)
VALUES
('Some text 1', GETDATE(), 1)
Заявление:
-- Declarations
DECLARE @stm nvarchar(max)
DECLARE @names nvarchar(max)
DECLARE @values nvarchar(max)
-- Dynamic part
SELECT
@values = STUFF((
SELECT CONCAT(N', CONVERT(varchar(max), ', QUOTENAME([COLUMN_NAME]), N') AS ', QUOTENAME([COLUMN_NAME]))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Data'
FOR XML PATH('')
), 1, 1, N''),
@names = STUFF((
SELECT CONCAT(N', ', QUOTENAME([COLUMN_NAME]))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Data'
FOR XML PATH('')
), 1, 1, N'')
-- Whole statement and execution
SELECT @stm =
CONCAT(
N'SELECT u.FieldName, u.FieldValue FROM (SELECT',
@values,
N'FROM Data) d UNPIVOT ([FieldValue] FOR [FieldName] IN (',
@names,
N')) u')
EXEC (@stm)
Выход:
-----------------------------------
FieldName FieldValue
-----------------------------------
ColumnVarchar Some text 1
ColumnDateTime Apr 29 2019 1:45PM
ColumnInt 1
Обновить - сохранить результаты в другую таблицу:
-- Whole statement and execution
SELECT @stm =
CONCAT(
N'SELECT u.FieldName, u.FieldValue INTO ResultTable FROM (SELECT',
@values,
N'FROM Data) d UNPIVOT ([FieldValue] FOR [FieldName] IN (',
@names,
N')) u')
EXEC (@stm)
SELECT *
FROM ResultTable