Pertanyaannya cukup jelas. Saya ingin melakukan pencarian dan penggantian sederhana, seperti yang Anda lakukan di editor teks pada data di kolom database saya (yaitu MsSQL di MS Windows server 2003)
Jawaban:
Kueri berikut mengganti setiap akarakter dengan bkarakter.
UPDATE
YourTable
SET
Column1 = REPLACE(Column1,'a','b')
WHERE
Column1 LIKE '%a%'
Ini tidak akan berfungsi di SQL server 2003.
WHERE?
seperti ini:
BEGIN TRANSACTION;
UPDATE table_name
SET column_name=REPLACE(column_name,'text_to_find','replace_with_this');
COMMIT TRANSACTION;
Contoh: Mengganti <script ... dengan <a ... untuk menghilangkan kerentanan javascript
BEGIN TRANSACTION; UPDATE testdb
SET title=REPLACE(title,'script','a'); COMMIT TRANSACTION;
<script>tag, seperti menggunakan <style>atau <object>tag, atau srcatribut atau atribut berbahaya onerror.
Ini mengarahkan saya ke arah yang benar, tetapi saya memiliki DB yang berasal dari MSSQL 2000 dan masih menggunakan ntexttipe data untuk kolom yang saya ganti. Saat Anda mencoba menjalankan REPLACE pada jenis itu, Anda mendapatkan kesalahan ini:
Tipe data argumen ntext tidak valid untuk argumen 1 dari fungsi pengganti.
Perbaikan paling sederhana, jika data kolom Anda cocok nvarchar, adalah dengan mentransmisikan kolom selama penggantian. Meminjam kode dari jawaban yang diterima :
UPDATE YourTable
SET Column1 = REPLACE(cast(Column1 as nvarchar(max)),'a','b')
WHERE Column1 LIKE '%a%'
Ini bekerja dengan sempurna untuk saya. Berkat posting forum ini saya menemukan untuk memperbaikinya. Semoga ini membantu orang lain!
Cukup ubah 'Search String'ke apa pun yang Anda cari dan 'Replace String'dengan apa pun yang ingin Anda gantikan.
--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
Catatan: ini tidak ideal, juga tidak dioptimalkan
Jika Anda bekerja dengan SQL Server 2005 atau yang lebih baru, ada juga pustaka CLR yang tersedia di http://www.sqlsharp.com/ yang menyediakan implementasi .NET dari fungsi string dan RegEx yang, bergantung pada volume dan jenis data Anda mungkin lebih mudah digunakan dan dalam beberapa kasus fungsi manipulasi string .NET bisa lebih efisien daripada yang T-SQL.