La question est assez explicite. Je veux faire une simple recherche et remplacement, comme vous le feriez dans un éditeur de texte sur les données d'une colonne de ma base de données (qui est MsSQL sur MS Windows Server 2003)
sql
sql-server
Jiaaro
la source
la source
WHERE
?ainsi:
BEGIN TRANSACTION; UPDATE table_name SET column_name=REPLACE(column_name,'text_to_find','replace_with_this'); COMMIT TRANSACTION;
Exemple: remplace <script ... par <a ... pour éliminer les vulnérabilités javascript
BEGIN TRANSACTION; UPDATE testdb SET title=REPLACE(title,'script','a'); COMMIT TRANSACTION;
la source
<script>
étiquette, comme l' utilisation<style>
ou<object>
balises ou malveillantssrc
attributs ouonerror
attributs.Cela m'a orienté dans la bonne direction, mais j'ai une base de données qui provient de MSSQL 2000 et qui utilise toujours le
ntext
type de données pour la colonne que je remplaçais. Lorsque vous essayez d'exécuter REPLACE sur ce type, vous obtenez cette erreur:La solution la plus simple, si les données de votre colonne s'inscrivent dans les limites
nvarchar
, consiste à convertir la colonne lors du remplacement. Emprunter le code de la réponse acceptée :UPDATE YourTable SET Column1 = REPLACE(cast(Column1 as nvarchar(max)),'a','b') WHERE Column1 LIKE '%a%'
Cela a parfaitement fonctionné pour moi. Merci à ce message de forum que j'ai trouvé pour le correctif. Espérons que cela aide quelqu'un d'autre!
la source
Les éléments suivants trouveront et remplaceront une chaîne dans chaque base de données (à l'exclusion des bases de données système) sur chaque table de l'instance à laquelle vous êtes connecté:
Changez simplement
'Search String'
pour ce que vous cherchez et'Replace String'
avec ce que vous voulez le remplacer.--Getting all the databases and making a cursor DECLARE db_cursor CURSOR FOR SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases DECLARE @databaseName nvarchar(1000) --opening the cursor to move over the databases in this instance OPEN db_cursor FETCH NEXT FROM db_cursor INTO @databaseName WHILE @@FETCH_STATUS = 0 BEGIN PRINT @databaseName --Setting up temp table for the results of our search DECLARE @Results TABLE(TableName nvarchar(370), RealColumnName nvarchar(370), ColumnName nvarchar(370), ColumnValue nvarchar(3630)) SET NOCOUNT ON DECLARE @SearchStr nvarchar(100), @ReplaceStr nvarchar(100), @SearchStr2 nvarchar(110) SET @SearchStr = 'Search String' SET @ReplaceStr = 'Replace String' SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128) SET @TableName = '' --Looping over all the tables in the database WHILE @TableName IS NOT NULL BEGIN DECLARE @SQL nvarchar(2000) SET @ColumnName = '' DECLARE @result NVARCHAR(256) SET @SQL = 'USE ' + @databaseName + ' SELECT @result = MIN(QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME)) FROM [' + @databaseName + '].INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_CATALOG = ''' + @databaseName + ''' AND QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME) > ''' + @TableName + ''' AND OBJECTPROPERTY( OBJECT_ID( QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME) ), ''IsMSShipped'' ) = 0' EXEC master..sp_executesql @SQL, N'@result nvarchar(256) out', @result out SET @TableName = @result PRINT @TableName WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) BEGIN DECLARE @ColumnResult NVARCHAR(256) SET @SQL = ' SELECT @ColumnResult = MIN(QUOTENAME(COLUMN_NAME)) FROM [' + @databaseName + '].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(''[' + @databaseName + '].' + @TableName + ''', 2) AND TABLE_NAME = PARSENAME(''[' + @databaseName + '].' + @TableName + ''', 1) AND DATA_TYPE IN (''char'', ''varchar'', ''nchar'', ''nvarchar'') AND TABLE_CATALOG = ''' + @databaseName + ''' AND QUOTENAME(COLUMN_NAME) > ''' + @ColumnName + '''' PRINT @SQL EXEC master..sp_executesql @SQL, N'@ColumnResult nvarchar(256) out', @ColumnResult out SET @ColumnName = @ColumnResult PRINT @ColumnName IF @ColumnName IS NOT NULL BEGIN INSERT INTO @Results EXEC ( 'USE ' + @databaseName + ' SELECT ''' + @TableName + ''',''' + @ColumnName + ''',''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) FROM ' + @TableName + ' (NOLOCK) ' + ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 ) END END END --Declaring another temporary table DECLARE @time_to_update TABLE(TableName nvarchar(370), RealColumnName nvarchar(370)) INSERT INTO @time_to_update SELECT TableName, RealColumnName FROM @Results GROUP BY TableName, RealColumnName DECLARE @MyCursor CURSOR; BEGIN DECLARE @t nvarchar(370) DECLARE @c nvarchar(370) --Looping over the search results SET @MyCursor = CURSOR FOR SELECT TableName, RealColumnName FROM @time_to_update GROUP BY TableName, RealColumnName --Getting my variables from the first item OPEN @MyCursor FETCH NEXT FROM @MyCursor INTO @t, @c WHILE @@FETCH_STATUS = 0 BEGIN -- Updating the old values with the new value DECLARE @sqlCommand varchar(1000) SET @sqlCommand = ' USE ' + @databaseName + ' UPDATE [' + @databaseName + '].' + @t + ' SET ' + @c + ' = REPLACE(' + @c + ', ''' + @SearchStr + ''', ''' + @ReplaceStr + ''') WHERE ' + @c + ' LIKE ''' + @SearchStr2 + '''' PRINT @sqlCommand BEGIN TRY EXEC (@sqlCommand) END TRY BEGIN CATCH PRINT ERROR_MESSAGE() END CATCH --Getting next row values FETCH NEXT FROM @MyCursor INTO @t, @c END; CLOSE @MyCursor ; DEALLOCATE @MyCursor; END; DELETE FROM @time_to_update DELETE FROM @Results FETCH NEXT FROM db_cursor INTO @databaseName END CLOSE db_cursor DEALLOCATE db_cursor
Remarque: ce n'est pas idéal, ni optimisé
la source
Si vous travaillez avec SQL Server 2005 ou version ultérieure, il existe également une bibliothèque CLR disponible à l' adresse http://www.sqlsharp.com/ qui fournit des implémentations .NET de chaînes et de fonctions RegEx qui, en fonction de votre volume et du type de données, peuvent être plus facile à utiliser et dans certains cas, les fonctions de manipulation de chaînes .NET peuvent être plus efficaces que celles de T-SQL.
la source