2015-01-21 2 views
2

이것은 아주 오래되었지만 여기에는 쉬운 대답이 없을 것입니다. 채워지는 데이터베이스를 상속 받았습니다. 끔찍한 데이터. 설명이 포함 된 많은 행에는 캐리지 리턴 문자가 있습니다. 즉, 데이터를 BCP 할 때 캐리지 리턴이 필요합니다.SQL Server- SQL 전체 데이터베이스의 모든 테이블에있는 모든 열을 대체하십시오.

내 질문에 : MS SQL Server의 전체 데이터베이스에서 전역 바꾸기를 수행 할 수있는 방법이 있습니까? 데이터베이스에는 수백 개의 테이블이 있으므로 테이블별로이 테이블을 수행하는 데 시간이 많이 걸릴 수 있습니다.

힌트 또는 팁을 주시면 감사하겠습니다.

미리 감사드립니다. 피트.

+0

BCP 중에 원하지 않는 문자를 제거 할 수 없습니까? – jazzytomato

+0

토마스에게 감사드립니다. 이것은 가능할 수도 있지만 소스에서 데이터를 정리하는 방법이있을 수 있기를 바랬습니다. 내가 길을 찾을 수 없으면 그 길을 확실히 보게 될 것입니다. 영감을 보내 주셔서 감사합니다. – PeteFoulkes

+0

메타 테이블/뷰를 쿼리하고 동적 SQL 업데이트를 생성하는 솔루션을 작성할 수 있습니다. –

답변

1

전체 DB에서 찾기 및 바꾸기를 원한다고 가정합니다. 그렇다면 try this script from MSSQLTIPS. 그것은 정확하게 그것을합니다. 당신이 시도 할 수

SET NOCOUNT ON 

DECLARE @stringToFind VARCHAR(100) 
DECLARE @stringToReplace VARCHAR(100) 
DECLARE @schema sysname 
DECLARE @table sysname 
DECLARE @count INT 
DECLARE @sqlCommand VARCHAR(8000) 
DECLARE @where VARCHAR(8000) 
DECLARE @columnName sysname 
DECLARE @object_id INT 

SET @stringToFind = 'Smith' 
SET @stringToReplace = 'Jones' 

DECLARE TAB_CURSOR CURSOR FOR 
SELECT B.NAME  AS SCHEMANAME, 
     A.NAME  AS TABLENAME, 
     A.OBJECT_ID 
FROM  sys.objects A 
     INNER JOIN sys.schemas B 
      ON A.SCHEMA_ID = B.SCHEMA_ID 
WHERE TYPE = 'U' 
ORDER BY 1 

OPEN TAB_CURSOR 

FETCH NEXT FROM TAB_CURSOR 
INTO @schema, 
    @table, 
    @object_id 

WHILE @@FETCH_STATUS = 0 
    BEGIN 
    DECLARE COL_CURSOR CURSOR FOR 
    SELECT A.NAME 
    FROM sys.columns A 
      INNER JOIN sys.types B 
      ON A.SYSTEM_TYPE_ID = B.SYSTEM_TYPE_ID 
    WHERE OBJECT_ID = @object_id 
      AND IS_COMPUTED = 0 
      AND B.NAME IN ('char','nchar','nvarchar','varchar','text','ntext') 

    OPEN COL_CURSOR 

    FETCH NEXT FROM COL_CURSOR 
    INTO @columnName 

    WHILE @@FETCH_STATUS = 0 
     BEGIN 
     SET @sqlCommand = 'UPDATE ' + @schema + '.' + @table + ' SET [' + @columnName 
          + '] = REPLACE(convert(nvarchar(max),[' + @columnName + ']),''' 
          + @stringToFind + ''',''' + @stringToReplace + ''')' 

     SET @where = ' WHERE [' + @columnName + '] LIKE ''%' + @stringToFind + '%''' 

     EXEC(@sqlCommand + @where) 

     SET @count = @@ROWCOUNT 

     IF @count > 0 
      BEGIN 
      PRINT @sqlCommand + @where 
      PRINT 'Updated: ' + CONVERT(VARCHAR(10),@count) 
      PRINT '----------------------------------------------------' 
      END 

     FETCH NEXT FROM COL_CURSOR 
     INTO @columnName 
     END 

    CLOSE COL_CURSOR 
    DEALLOCATE COL_CURSOR 

    FETCH NEXT FROM TAB_CURSOR 
    INTO @schema, 
     @table, 
     @object_id 
    END 

CLOSE TAB_CURSOR 
+0

완벽! 이것은 황금이다. 내 요구 사항을 충족시키기 위해 약간 조정했지만 완벽하게 작동합니다. 귀하의 의견을 보내 주셔서 감사합니다. – PeteFoulkes

+0

@PeteFoulkes 문제 없습니다. 이 질문에 답을 얻은 경우 솔루션으로 표시 할 수 있습니다. :) – Arun

+0

다시 한번 고마워. 나는 정답이라고 표시했습니다. – PeteFoulkes

1

: 여기

는 전체 스크립트입니다

declare @charToReplace varchar(10) = 'char(13)' -- Carriage Return, CHAR(10) for line feed. Needs to be enclosed on quotes 

select ROW_NUMBER() OVER (ORDER BY name) as ID 
    , name as TableName 
into #tables 
from sys.tables 

declare @Counter int = 0 
declare @TotalTables int = (select COUNT(1) from #tables) 

while @Counter < @TotalTables 
begin 

    declare @CurrTableName varchar(128) = (select TableName from #tables where ID = (@Counter + 1)) 
    declare @Columns nvarchar(4000) = '' 
    declare @SQLQuery nvarchar(4000) = '' 

    SELECT @Columns = COALESCE(@Columns + ',' , '') + c.name + ' = REPLACE(' + c.name + ', ' + @charToReplace + ', '''')' 
    FROM SYS.tables t 
     INNER JOIN sys.columns c 
      ON C.object_id = t.object_id 
    where t.name = @CurrTableName 
     and c.user_type_id in (167, 231, 239) 

    set @SQLQuery = 'UPDATE ' + @CurrTableName + ' SET ' + SUBSTRING(@Columns, 2, LEN(@Columns)) 

    print @SQLQuery -- You can change this to EXEC SP_EXECutesql @SQLQuery 

    set @Counter += 1; 

end 

drop table #tables 

나는이 테스트를하지 않은,하지만 난 당신이 찾고있는 솔루션으로 당신을 이끌 수 있기를 바랍니다 .

참고 : print @SQLQueryEXEC SP_EXECutesql @SQLQuery으로 바꿔야하므로 DB에서 변경 작업을 수행 할 수 있습니다.

관련 문제