source

MsSQL에서 간단한 '찾기 및 바꾸기'를 수행하려면 어떻게 해야 합니까?

lovecheck 2023. 5. 27. 11:48
반응형

MsSQL에서 간단한 '찾기 및 바꾸기'를 수행하려면 어떻게 해야 합니까?

질문은 꽤 자기 설명적입니다.데이터베이스의 열에 있는 데이터에 대한 텍스트 편집기의 경우처럼 간단한 찾기 및 바꾸기를 수행합니다(MS Windows Server 2003의 경우 MsSQL).

다음 쿼리는 각 항목을 바꿉니다.a의 성격.b성격.

UPDATE 
    YourTable
SET 
    Column1 = REPLACE(Column1,'a','b')
WHERE 
    Column1 LIKE '%a%'

SQL Server 2003에서는 작동하지 않습니다.

이와 같이:

BEGIN TRANSACTION; 
UPDATE table_name
  SET column_name=REPLACE(column_name,'text_to_find','replace_with_this'); 
COMMIT TRANSACTION;

예: <script...>를 대체합니다.<a...를 사용하여 Javascript 취약성 제거

BEGIN TRANSACTION; UPDATE testdb
SET title=REPLACE(title,'script','a'); COMMIT TRANSACTION;

이것은 나에게 올바른 방향을 가리켰지만, 나는 MSSQL 2000에서 시작된 DB를 가지고 있고 여전히 사용하고 있습니다.ntext교체할 열의 데이터 형식입니다.해당 유형에서 REPLACE를 실행하려고 하면 다음 오류가 발생합니다.

바꾸기 함수의 인수 1에 대한 인수 데이터 형식 ntext가 잘못되었습니다.

열 데이터가 적합한 경우 가장 간단한 수정 방법nvarchar교체 중에 기둥을 주조하는 것입니다.승인된 답변에서 코드 차용:

UPDATE YourTable
SET Column1 = REPLACE(cast(Column1 as nvarchar(max)),'a','b')
WHERE Column1 LIKE '%a%'

이것은 저에게 완벽하게 효과가 있었습니다.포럼 게시물 덕분에 수정할 수 있었습니다.이것이 다른 누군가에게 도움이 되기를 바랍니다!

다음은 연결된 인스턴스의 모든 테이블에 있는 모든 데이터베이스(시스템 데이터베이스 제외)에서 문자열을 찾아 바꿉니다.

간단히 변경'Search String'당신이 찾는 것은 무엇이든.'Replace String'당신이 대체하고 싶은 것으로.

--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

참고: 이것은 이상적이지도 않고 최적화되지도 않습니다.

SQL Server 2005 이상을 사용하는 경우에는 .NET의 문자열 및 ReGEx 함수 구현을 제공하는 CLR 라이브러리도 http://www.sqlsharp.com/ 에 있습니다. 이 라이브러리는 볼륨 및 데이터 유형에 따라 사용하기가 더 쉬울 수 있으며 경우에 따라 .NET 문자열 조작 기능이 T-SQL 라이브러리보다 더 효율적일 수 있습니다.

언급URL : https://stackoverflow.com/questions/59044/how-do-i-do-a-simple-find-and-replace-in-mssql

반응형