La pregunta se explica por sí misma. Quiero hacer una búsqueda y reemplazo simple, como lo haría en un editor de texto en los datos en una columna de mi base de datos (que es MsSQL en MS Windows Server 2003)
sql
sql-server
Jiaaro
fuente
fuente
WHERE
?al igual que:
BEGIN TRANSACTION; UPDATE table_name SET column_name=REPLACE(column_name,'text_to_find','replace_with_this'); COMMIT TRANSACTION;
Ejemplo: Reemplaza <script ... con <a ... para eliminar vulnerabilidades de JavaScript.
BEGIN TRANSACTION; UPDATE testdb SET title=REPLACE(title,'script','a'); COMMIT TRANSACTION;
fuente
<script>
etiqueta, como el uso<style>
o<object>
etiquetas, o maliciosossrc
atributos oonerror
atributos.Esto me indicó la dirección correcta, pero tengo una base de datos que se originó en MSSQL 2000 y todavía
ntext
estoy usando el tipo de datos para la columna que estaba reemplazando. Cuando intenta ejecutar REPLACE en ese tipo, aparece este error:La solución más simple, si los datos de la columna encajan dentro
nvarchar
, es convertir la columna durante el reemplazo. Tomando prestado el código de la respuesta aceptada :UPDATE YourTable SET Column1 = REPLACE(cast(Column1 as nvarchar(max)),'a','b') WHERE Column1 LIKE '%a%'
Esto funcionó perfectamente para mí. Gracias a esta publicación del foro que encontré por la solución. ¡Ojalá esto ayude a alguien más!
fuente
Lo siguiente buscará y reemplazará una cadena en cada base de datos (excluyendo las bases de datos del sistema) en cada tabla en la instancia a la que está conectado:
Simplemente cambie
'Search String'
a lo que busque y'Replace String'
con lo que quiera reemplazarlo.--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
Nota: esto no es ideal ni está optimizado
fuente
Si está trabajando con SQL Server 2005 o posterior, también hay una biblioteca CLR disponible en http://www.sqlsharp.com/ que proporciona implementaciones .NET de funciones de cadena y RegEx que, dependiendo de su volumen y tipo de datos, pueden ser más fácil de usar y, en algunos casos, las funciones de manipulación de cadenas de .NET pueden ser más eficientes que las de T-SQL.
fuente