Connexion



Register
Forgot Password ?

Inscription

L'inscription à DotNetNuke France est entièrement gratuite et vous permet de profiter pleinement des outils mis à votre disposition. L'inscription ne donne néanmoins pas le statut d'adhérent à l'association.

  • Discutez sur le forum et suivez son activité
  • Répondez aux articles
  • Soutenez l'association
  • Téléchargez les traductions

 

DotNetNuke France

Association francophone

Changer l'URL d'un site DotNetNuke

Auteur : Sébastien Fichot

Date de pulication : 08 June 2010

Classement : Développement

Article consulté 1619 fois Article Rating (4 votes)
 

Voici un script qui permet de changer l'URL d'un site DotNetNuke en modifiant l'ensemble des contenus présents dans la base de données.
Ce script va parcourir l'ensemble des tables, colonnes et entrées de la base de donnée dans laquelle il s'éxécute (une base DotNetNuke par exemple) et va remplacer le contenu de la valeur de "@condition" par la valeur de "@replacestring". Dans cet exemple, le script est utilisé pour migrer les URLs d'un site DotNetNuke, mais vous pouvez utiliser n'importe quelle valeur (email, terme, faute d'orthographe, constitution rapide d'un wiki ...).

Exécuter le script

Pour exécuter le script, lancez SQL Server Management Studio, connectez vous à un moteur SQL, puis créez un nouveau script à l'intérieur duquel vous collez le script tel que présenté plus bas. Le script a été testé avec SQL 2005 et SQL 2008. Il  fonctionnera probablement avec SQL 2000. Vous pouvez aussi télécharger le script depuis la librairie et l'ouvrir avec SQL Server Management Studio.





La table sélectionnée constitue la table sur laquelle le script s'exécutera.



Commencez par éditer la condition de remplacement (Cf. "@Condition" ligne 86). La "condition" contient la valeur qui sera modifiée. Editez ensuite la valeur de remplacement (Cf. "@ReplaceString" ligne 87). La valeur de remplacement remplacera après l'exécution du script la valeur "condition", et ce, sur l'ensemble des tables de la base de données. 



Même si cela fonctionne, je ne vous recommande pas d'exécuter le script depuis le menu Hôte > SQL car vous ne verrez pas un éventuel message d'erreur.

La méthode n'est pas parfaite, car par exemple elle ne permet pas de se restreindre à un portail uniquement. Le changement est effectif sur l'ensemble des sites sur lesquels @Condition est trouvé et remplacé. Le script ne traite également pas plus de 4 clefs primaire sur une table. La suite aurait été trop longue à écrire, mais cela suffit largement pour le moment pour Dnn 2, Dnn 3, Dnn 4 et Dnn 5. Egalement, il ne traite pas les tables qui n'ont pas de clef primaire. Toutes ces tables qui ne seront pas traitées seront listées dans la fenêtre des messages.

Je ne vous recommande pas spécialement de remplacer "monURL" par "MaSuperLongueURL" car si le champ est presque à sa valeur maximale, vous pourrez provoquer l'échec de l'update (qui sera bien entendu listé lui aussi). Considérez cela au moment où vous choisissez votre URL de développement.

Désactiver le mode de test

Exécutez d'abord le script en mode de test. La mode mode de test est activé nativement. Vous devez manuellement commenter les RollBack pour que le script soit effectif.






License

Ce texte est publié sous la licence Creative Commons Paternité-Partage des Conditions Initiales à l'Identique 3.0 Unported.  

* Vous êtes libres :
  • de reproduire, distribuer et communiquer cette création au public.
  • de modifier cette création.
* Selon les conditions suivantes :
  • - Paternité
    Vous devez citer le nom de l'auteur original de la manière indiquée par l'auteur de l'oeuvre ou le titulaire des droits qui vous confère cette autorisation (mais pas d'une manière qui suggérerait qu'ils vous soutiennent ou approuvent votre utilisation de l'oeuvre).
  • - Partage des Conditions Initiales à l'Identique
    Si vous transformez ou modifiez cette oeuvre pour en créér une nouvelle, vous devez la distribuer selon les termes du même contrat ou avec une licence similaire ou compatible.
* Notice
  • A chaque réutilisation ou distribution de cette création, vous devez faire apparaître clairement au public les conditions contractuelles de sa mise à disposition. La meilleure manière de les indiquer est un lien vers cette page web.
* UPDATE : 21 Août 2010 : - Allongement des variables contenant les noms des colonnes et des tables de manière dynamiques à 100 caractères. Le script échouait si le nom de la base ou de la colonne était supérieur à 30 caractères. - Ajout de la suppression sous condition des tables temporaires au cas où le script est ré-exécuté suite à une erreur.



	--Ce script va parcourir l'ensemble des tables, colonnes et entrées de la base de donnée dans laquelle 
	--il s'éxécute (une base DotNetNuke par exemple) et va remplacer le contenu de la valeur de "@condition" 
	--par la valeur de "@replacestring".
	--Dans cet exemple, le script est utilisé pour migrer les URLs d'un site DotNetNuke, mais vous pouvez
	--utiliser n'importe quelle valeur (email, terme, faute d'orthographe, constitution rapide d'un wiki ...)
		
	--This script will browse the whole content of a given database (Table, Row, Entry only) - a DotNetNuke DataBase 
	--for instance - and replace the value of "@condition" by the value of "@replacestring".
	--In this example, the script is used to replace the URLs of a DotNetNuke website when you which to migrate to a 
	--new domain, from development instance to prod instance for example, but can be used for or lot of other scenarios
	--( Replace email, replace term, ...)	
	
	
	--Le nombre de clés primaire sur les tables de la base est limitté à 4. (Suffisant pour DotNetNuke)
	
	--Le script ne traitera pas les tables sans clé primaire. Il listera à la fin toute table sans PK.
	
	--Les champs < 4000 caractères seront transformés en nvarchar pour traitement puis retransformés 
	--dans leur type initial pour insertion car REPLACE ne traite pas plus de 4000 caractères 
	--(donc cas du nvarchar(4001 et +) non traité).
	
	--Les champs ntext sont mis à jour avec UPDATETEXT.
	
	--Attention! il y a deux rollback. Si vous voulez enregistrer les modifications de la base,
	--	   il faudra supprimer la transaction avant l'exécution de ce script.
	--	   Donc après les tests, commenter "begin tran" et "rollback tran" pour passer
	--	   à une éxécution effective (ligne 246 et 250 et ligne 319 et 323).

	
	
	
	--Ce texte est publié sous la licence Creative Commons Paternité-Partage des Conditions Initiales 
	--à l'Identique 3.0 Unported. http://creativecommons.org/licenses/by-sa/3.0/deed.fr
	--* Vous êtes libres : 
	--	de reproduire, distribuer et communiquer cette création au public.
	--	de modifier cette création.
	
	--* Selon les conditions suivantes :
	--	- Paternité
	--		Vous devez citer le nom de l'auteur original de la manière indiquée par l'auteur de 
	--		l'oeuvre ou le titulaire des droits qui vous confère cette autorisation (mais pas d'une 
	--		manière qui suggérerait qu'ils vous soutiennent ou approuvent votre utilisation de l'oeuvre).
	--	- Partage des Conditions Initiales à l'Identique
	--		Si vous transformez ou modifiez cette oeuvre pour en créér une nouvelle, vous devez la 
	--		distribuer selon les termes du même contrat ou avec une licence similaire ou compatible.
			

	--With the understanding that:
	--	- Waiver
	--		Any of the above conditions can be waived if you get permission from the copyright holder.
	--	- Public Domain
	--		Where the work or any of its elements is in the public domain under applicable law, that 
	--		status is in no way affected by the license.
	--	- Other Rights - In no way are any of the following rights affected by the license:
	--		- Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;
	--		- The author's moral rights;
	--		- Rights other persons may have either in the work itself or in how the work is used, such as publicity or privacy rights.

	--Notice
	--	A chaque réutilisation ou distribution de cette création, vous devez faire apparaître clairement au public 
	--	les conditions contractuelles de sa mise à disposition. La meilleure manière de les indiquer est un 
	--	lien vers cette page web.
	

BEGIN
	print 'Décommentez "begin tran" et "rollback tran" pour que le script s''execute réellement.'
	print 'Le script ne traitera pas les tables sans clé primaire listées ci-après.'
END

set nocount on 

declare @condition nvarchar(400) 
declare @replacestring nvarchar(400)

set @condition = 'www.dotnetnuke.fr' -- Ancienne URL
set @replacestring = 'www.dotnetnuke-fr.org' -- Nouvelle URL


-- Supprime les tables temporaires en cas de répétition sur une éxécution qui avait échoué.
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[t_Res]') AND type in (N'U'))
DROP TABLE t_Res
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[aspnet_Applications]') AND type in (N'U'))
DROP TABLE t_ResExclu
GO

-- Tables de resultats temporaires (sera supprimée ensuite)
create table t_ResExclu ( table_name varchar(100) , column_name varchar(100))
create table t_Res ( table_name varchar(100) , column_name varchar(100) , Id1 varchar(100) , Id2 varchar(100) , Id3 varchar(100) , Id4 varchar(100) , res int , column_content varchar(8000) , column_lenght int ) declare @table_name varchar(100) declare @column_name varchar(100) declare @sqlSelect nvarchar(4000) declare @sqlUpdate nvarchar(4000) declare @nblen int declare @Id1 nvarchar(100), @Id2 nvarchar(100), @Id3 nvarchar(100), @Id4 nvarchar(100), @IdT nvarchar(100), @Clmn nvarchar(300), @ClmnNtext nvarchar(300), @Clmnfetch nvarchar(300), @ClmnUpText nvarchar(300), @JoinClmn nvarchar(300), @nbID smallint, @Nb_enr int declare table_list



-- Parcours l'ensemble des tables de la base de données sélectionnée
cursor FAST_FORWARD READ_ONLY
	for
		select table_name
		from information_schema.tables
		where table_type = 'BASE TABLE' 
		-- Activez le paramètre suivant pour restrindre la recherche/remplacement à une seule table
		--and  table_name = 'EventLog'

		open table_list fetch next
			 from table_list into @table_name 
				while @@fetch_status=0 begin
				 
				 set @ID1 = null
				 set @ID2 = null
				 set @ID3 = null
				 set @ID4 = null
				 set @Clmn = ''
				 set @ClmnNText = ''
				 set @ClmnFetch = ''
				 set @JoinClmn = ''
				 set @nbID = null
				 set @ClmnUpText = ''
	
				-- Compte les cles primaires des tables parcourues
				 select @nbID= count(c.column_name)
				 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk 
					, INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
				 where pk.table_name = @Table_Name
				 and CONSTRAINT_TYPE = 'PRIMARY KEY'
				 and c.table_name = pk.table_name
				 and c.constraint_name = pk.constraint_name 

				if @nbID > 0 
					begin 
						declare IDlist
						 cursor FAST_FORWARD READ_ONLY
							 for
								-- Liste les cleés primaires
								 select c.column_name
								 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk 
									, INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
								 where pk.table_name = @Table_Name
								 and CONSTRAINT_TYPE = 'PRIMARY KEY'
								 and c.table_name = pk.table_name
								 and c.constraint_name = pk.constraint_name 

								 open IDlist fetch next
								 from IDlist into @IdT 
									while @@fetch_status=0 
									begin 
										if @ID1 is null 
										begin
											 set @ID1 = @IdT
											 set @Clmn = ' ' + @IdT + ' Id1'
											 set @JoinClmn = ' ON T.' + @IdT + ' =  R.Id1'
											 set @ClmnUpText = @IdT + ' =  @Id1'
											 set @ClmnFetch = '@Id1' 
										end 
										else if @ID2 is null 
												begin
													 set @ID2 = @IdT
													 set @Clmn = @Clmn + ', ' + @IdT + ' Id2'
													 set @JoinClmn = @JoinClmn + ' And T.' + @IdT + ' =  R.Id2'
													 set @ClmnUpText = @ClmnUpText + ' AND ' + @IdT + ' =  @Id2'
													 set @ClmnFetch = @ClmnFetch + ', @Id2' 
												end 
										else if @ID3 is null 
													begin
														 set @ID3 = @IdT
														 set @Clmn = @Clmn + ', ' + @IdT + ' Id3'
														 set @JoinClmn = @JoinClmn + ' And T.' + @IdT + ' =  R.Id3'
														 set @ClmnUpText = @ClmnUpText + ' AND ' + @IdT + ' =  @Id3'
														 set @ClmnFetch = @ClmnFetch + ', @Id3' 
													end 
										else if @ID4 is null 
														begin
															 set @ID4 = @IdT
															 set @Clmn = @Clmn + ', ' + @IdT + ' Id4'
															 set @JoinClmn = @JoinClmn + ' and T.' + @IdT + ' =  R.Id4'
															 set @ClmnUpText = @ClmnUpText + ' AND ' + @IdT + ' =  @Id4'
															 set @ClmnFetch = @ClmnFetch + ', @Id4' 
														end 

										fetch next

										from IDlist into @IdT 

									end 
									close IDlist 
									deallocate IDlist

									 set @ClmnNtext = @Clmn 
									while @nbID < 4 
										begin
											set @nbID = @nbID + 1
											set @Clmn = @Clmn + ', Null Id' + convert(char(1), @nbID) 
									end 
									
									-- Liste les colonnes
									declare column_list
									 cursor FAST_FORWARD READ_ONLY
										 for
										 select column_name , 
										case when CHARACTER_MAXIMUM_LENGTH > 4000 then 4000
										else CHARACTER_MAXIMUM_LENGTH
										end nblen
										 from information_schema.columns 
										where table_name = @table_name
										 and data_type not in ('image', 'money')
										 and CHARACTER_MAXIMUM_LENGTH is not null 

										open column_list 
											fetch next
											 from column_list into @column_name, @nblen 
												while @@fetch_status=0 
													begin 
													-- Decommentez la ligne suivante pour afficher le nom de toutes les colonnes parcourues
													 -- print @table_name + ' -- ' + @column_name
													
													 set @sqlSelect = N' Select ' + char(39) + @table_name + char(39) + ' table_name, ' + char(39) + @column_name + char(39) + ' column_name, ' + @Clmn + ' , 1 res, convert(nvarchar(' + convert(nvarchar(100), @nblen) + '), [' + @column_name + ']) column_content ,  len(convert(varchar(8000), [' + @column_name + '])) column_lenght from ' + @table_name + ' where [' + @column_name + '] like ' + char(39) + '%' + @condition + '%' + char(39) 
													 -- Decommentez la ligne suivante pour afficher l'ensemble des requêtes SELECT effectuées
													 --print @sqlSelect

													 insert into t_Res 
													 exec sp_executesql @sqlSelect

													 set @nb_enr = 0
													 select @nb_enr= count(*)
													 from t_res
	
													 if @Id1 is not null and @nb_enr > 0 
														begin 
															if not exists(select max(column_lenght)
															   from t_Res
															   where res = 1
															   group by column_lenght 
															   having max(column_lenght) > 4000) 

																begin 

																	set @sqlUpdate = N' update ' + @table_name + ' Set [' + @column_name + '] = replace(convert(nvarchar(' + convert(nvarchar(100), @nblen) + '), [' + @column_name + ']), ' + char(39) + @condition + char(39) + ' , ' + char(39) + @replacestring + char(39) + ') ' + ' From ' + @table_name + ' T inner join t_Res R ' + @JoinClmn 
																	-- Decommentez la ligne suivante pour afficher l'ensemble des requêtes UPDATE effectuées
																	-- print @sqlUpdate
																	-- print @sqlSelect
																	print 'Colonne mise à jour : [' + @column_name + '] de la table [' + @table_name + ']'

																	-- Ici vous pouvez effectuer un traitement particulier sur les données d'une colonne
																	--	if @Id1 = 'ApplicationId' begin 
																	--		...
																	--	end
					
																	begin tran -- Commentez cette ligne pour effectuer les changements

																		exec sp_executesql @sqlUpdate

																	rollback tran -- Commentez cette ligne pour effectuer les changements
																end
													 if exists(select *
															   from t_Res
															   where column_lenght > 4000) 
														begin
															insert into t_ResExclu (table_name, column_name)
															 values (@table_name, @column_name)

															 if exists(select data_type
																   from information_schema.columns
																   where table_name = @table_name
																		and column_name = @column_name
																		and data_type = 'ntext') 
																begin 
																-- Cas NTEXT
																-- On traite les colonnes exclues par la premiere methode uniquement
																-- et jusqu'à 4 clés primaires
																	if CHARINDEX(@condition, @replacestring) > 0 
																		begin 
																			PRINT 'La valeur de remplacement contient la valeur a remplacer. Cela produira un LOOP. 
																				   Veuillez changer la valeur de remplacement 
																				  (ou executez la demarche en deux fois, par exemple, pour transformer 1234 en 123456 :
																					remplacer d abord 1234 en XXXX, puis XXXX en 123456)' 
																		end 
																	else 
																		begin
																			set @sqlUpdate = N'
																				declare @lenOldString INT
																					  , @Id1 nvarchar(100)
																					  , @Id2 nvarchar(100)
																					  , @Id3 nvarchar(100)
																					  ,	@Id4 nvarchar(100)
																					  , @TextPointer BINARY(16)
																					  , @TextIndex INT
																				SET @lenOldString = DATALENGTH(' + char(39) + @condition + char(39) + ')
																				DECLARE irows CURSOR
																				LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
																					SELECT ' + @ClmnNtext + ' 
																					FROM ' + @table_name + '
																					WHERE PATINDEX(' + char(39) + '%' + @condition + '%' + char(39) + ', ' + @column_name + ') > 0
																						OPEN irows
																						FETCH NEXT FROM irows INTO ' + @ClmnFetch + '
																							WHILE (@@FETCH_STATUS = 0)
																							BEGIN
																								SELECT
																									@TextPointer = TEXTPTR(' + @column_name + '),
																									@TextIndex = PATINDEX(' + char(39) + '%' + @condition + '%' + char(39) + ', ' + @column_name +')
																								FROM  ' + @table_name + ' WHERE ' + @ClmnUpText + '
																								WHILE
																								(
																									SELECT
																										PATINDEX(' + char(39) + '%' + @condition + '%' + char(39) + ', ' + @column_name +')
																									FROM  ' + @table_name + ' WHERE ' + @ClmnUpText + '
																								) > 0
																								BEGIN
																									SELECT
																										@TextIndex = PATINDEX(' + char(39) + '%' + @condition + '%' + char(39) + ', ' + @column_name +')-1
																									FROM  ' + @table_name + ' WHERE ' + @ClmnUpText + '

																									UPDATETEXT ' + @table_name + '.' + @column_name + ' @TextPointer @TextIndex @lenOldString ' + char(39) + @replacestring + char(39) + '
																								END
																								FETCH NEXT FROM irows INTO  ' + @ClmnFetch + '
																							END
																				CLOSE irows
																				DEALLOCATE irows' 

																				-- print @sqlUpdate

																				begin tran -- Commentez cette ligne pour effectuer les changements

																					exec sp_executesql @sqlUpdate 

																				rollback tran -- Commentez cette ligne pour effectuer les changements

																			end 
																		end 
																	end 
																end 

												truncate table t_Res 

												fetch next
															 
												from column_list into @column_name , @nblen 
										end 
									close column_list 
									deallocate column_list 
								end 
								else 
								begin 
									print 'Table sans PK : ' + @table_name 
									-- Traitement particulier des tables sans PK ?

								end 
					fetch next
					from table_list into @table_name 
				end 
	close table_list 
deallocate table_list 
--select * from t_Res order by convert(int, column_name) desc
--select max(column_lenght) from t_Res   where res = 1 group by column_lenght having max(column_lenght) > 4000

-- Affiche les colonnes traitées en NTEXT
-- print 'Table traitées en NTEXT : ' 
-- select table_name table_name_ntext, column_name column_name_ntext from t_ResExclu

drop table t_Res
drop table t_ResExclu


Merci à Abdellah BELHADDAD pour son aide et son soutien pendant la longue après-midi d'écriture de ce script testé une bonne dizaine de fois.

 

Notez cet article !

DotNetNuke c'est ...

  • Facile à utiliser
  • Open Source et gratuit
  • 100% personnalisable
  • Des milliers d'extensions
  • Multilingue
  • Multi-site
  • Maintenu par une communauté d'experts
  • Sécurisé

Restez informé !

Inscrivez vous pour recevoir notre lettre d'information.

x

Restez connecté !

Le fichier que vous téléchargez sera probablement mis à jour très bientôt.

Inscrivez vous
et nous vous informerons des mises à jour