web-dev-qa-db-fra.com

Sélectionnez des colonnes de manière dynamique à partir de la table SQL Server

Disons que j'ai une table qui stocke réellement l'enregistrement qui ressemble à

Create Table dbo.Info
(
 SN int primary key identity(1,1),
 FirstName nvarchar(50) not null,
 LastName nvarchar(50) not null,
 Gender char(1) default 'M',
 Age int check(Age>0)
)

Maintenant, pour le signalement, j'ai seulement besoin de ce nom de colonne de table et de sauvegarder dans une autre table.

Create Table Report.InfoColumnOrder
(
 SN int primary key identity(1,1),
 UserId int,
 ColumnName nvarchar(100)
)

ainsi, l'enregistrement ressemble à

1, 1, FirstName
2, 1, LastName
3, 1, Gender
4, 2, LastName
5, 2, FirstName
6, 2, Age
7, 2, Gender

Maintenant, lorsque l'utilisateur avec ID 1 Login et veut un rapport de la table Info Select, la commande doit ressembler

Select FirstName, LastName, Gender from dbo.Info

tandis que pour un utilisateur avec la commande ID 2 Select sera

Select LastName, FirstName, Age, Gender from dbo.Info

Étant donné que l'utilisateur peut commander la colonne à partir de la déclaration de sélection du côté client doit être dynamique. C'est possible?

5
Bhuban

Utilisez Dynamic SQL. Mais rejoignez Sys.Columns pour éviter les attaques d'injection SQL.

DECLARE @qry NVARCHAR(MAX) =
'SELECT ' + STUFF((
    SELECT ', ' + QUOTENAME(c.name) 
    FROM Report.InfoColumnOrder r
    JOIN sys.columns c ON c.name = r.ColumnName AND c.object_id = object_id('dbo.Info')
    WHERE u.UserId = @user
    ORDER BY r.SN
    FOR XML PATH(''), TYPE).value('.','nvarchar(max)'),1,2,'') +
 ' FROM dbo.Info'
;
EXEC sp_executesql @qry, N'@user int', @user = @userid;

Ou quelque chose comme ça - j'écris ceci sur mon téléphone ...

4
Rob Farley