J'ai déjà écrit une procédure stockée qui faisait juste quelque chose comme ça. Sont donnés une table d'utilisateurs avec des détails de base et un nombre variable de propriétés de profil pour les utilisateurs. (Le nombre de propriétés de profil varie selon le portail DotNetNuke)
Ceci est directement à partir de DotNetNuke 4.9, vérifiez le schéma de la base de données à partir de là et vous obtiendrez les détails. Tables impliquées sont des utilisateurs, UserPortals, UserProfile, ProfilePropertyDefinition
En bref mots:
- Je crée une table temporaire avec toutes les propriétés de profil sous forme de colonnes (dynamiquement)
- je remplir la table temporaire avec userid (comme clé étrangère pour relier à la table des utilisateurs et toutes les propriétés du profil des données
- Je rejoins une table sur les utilisateurs et table temporaire
Cela me donne une ligne pe r utilisateur avec toutes les propriétés de profil.
Voici le code - pas parfait mais bon son sur mesure pour mes besoins mais devrait être assez facile à réutiliser (essayé d'éviter les curseurs btw)
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[rows2cols] @portalId INT
AS BEGIN
print 'PortalID=' + convert(varchar,@portalId)
--SET NOCOUNT ON;
declare @idx int
declare @rowcount int
declare @tmpStr nvarchar(max)
declare @ctype nvarchar(max)
declare @cname nvarchar(max)
declare @clen int
declare @createStr nvarchar(max)
---------------------------------------------------------------------------
-- create tmp table --
---------------------------------------------------------------------------
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[xxxx]') AND type in (N'U'))
DROP TABLE [dbo].[xxxx]
print 'Building Temp Table Cols for profile properties...'
set @rowcount = (select count(*) from ProfilePropertyDefinition where PortalID=0 and deleted=0)
set @idx = 1
set @tmpStr = ''
while (@idx <= @rowcount)
begin
-- dynamically generate rownumbers to be able to do loop over them (avoid cursors)
select @cname = t1.PropertyName from
(select ROW_NUMBER() OVER (ORDER BY ViewOrder) as Idx, PropertyName from ProfilePropertyDefinition
where PortalID=0 and deleted=0
) as t1 where t1.Idx = @idx
if (@cname = 'Email' or @cname = 'FirstName' or @cname = 'LastName') begin
set @clen = 1
end else begin
set @tmpStr = @tmpStr + '[' + @cname + '] [nvarchar](500), '
end
set @idx = @idx + 1
end
set @tmpStr = @tmpStr + '[userid] [int] '
set @createStr = 'create table xxxx (' + @tmpStr + ')'
Print @createStr
Exec (@createStr)
---------------------------------------------------------------------------
-- fill tmp table --
---------------------------------------------------------------------------
declare @propName nvarchar(max)
declare @propVal nvarchar(max)
declare @userId int
declare @idx2 int
declare @rowcount2 int
declare @inscol nvarchar(max)
declare @insval nvarchar(max)
set @rowcount = (select count(*) FROM Users LEFT OUTER JOIN UserPortals ON Users.UserID = UserPortals.UserId WHERE UserPortals.PortalId = @portalId)
set @idx = 1
while (@idx <= @rowcount)
begin
-- get userId
select @userId = t1.UserID from (select u.UserID, ROW_NUMBER() OVER (ORDER BY u.UserID) as Idx
from Users as u LEFT OUTER JOIN UserPortals as up ON u.UserID = up.UserId where up.PortalId = @portalId) as t1
where t1.Idx = @idx
set @idx2 = 1
set @rowcount2 = (select count(*) from UserProfile where UserID = @userId)
set @inscol = ''
set @insval = ''
while (@idx2 < @rowcount2)
begin
-- build insert for a specific user
select @propName = t1.PropertyName , @propVal=t1.PropertyValue from
(select ROW_NUMBER() OVER (ORDER BY ProfileID) as Idx, up.PropertyDefinitionID,ppd.PropertyName, up.PropertyValue
from UserProfile as up
inner join ProfilePropertyDefinition as ppd on up.PropertyDefinitionID = ppd.PropertyDefinitionID
where UserID = @userId
) as t1 where t1.Idx = @idx2
if (@propName != 'Firstname' and @propName != 'LastName' and @propName != 'Email')
begin
set @inscol = @inscol + @propName + ', '
set @insval = @insval + 'N''' + replace(@propVal,'''','''''') + ''', '
end
set @idx2 = @idx2 + 1
end
set @inscol = @inscol + 'userid'
set @insval = @insval + convert(nvarchar,@userId)
set @tmpStr = 'insert into xxxx (' + @inscol + ') values (' + @insval + ')'
--print @tmpStr
Exec(@tmpStr)
set @idx = @idx + 1
end
-- -------------------------------------------------------------------------
-- return tmp table & dump --
-- -------------------------------------------------------------------------
SELECT Users.*, xxxx.* FROM xxxx INNER JOIN Users ON xxxx.userid = Users.UserID
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[xxxx]') AND type in (N'U'))
DROP TABLE [dbo].[xxxx]
END
Est-ce que Tableau2 ont une BlockDate par ligne? Quel est le lien entre Table1 et Table2? Vous cherchez probablement un pivot. – DyingCactus