【问题标题】:Adapt Replace all strings in all tables to work with text调整替换所有表中的所有字符串以使用文本
【发布时间】:2010-09-07 13:39:05
【问题描述】:

我有以下脚本。它用@replaceWith 替换数据库中所有表中的所有@lookFor 实例。但是它不适用于只有 varchar 等的文本字段。这可以轻松适应吗?

------------------------------------------------------------
-- Name: STRING REPLACER
-- Author: ADUGGLEBY
-- Version: 20.05.2008 (1.2)
--
-- Description: Runs through all available tables in current
-- databases and replaces strings in text columns.
------------------------------------------------------------

-- PREPARE
SET NOCOUNT ON

-- VARIABLES
DECLARE @tblName NVARCHAR(150)
DECLARE @colName NVARCHAR(150)
DECLARE @tblID int
DECLARE @first bit
DECLARE @lookFor nvarchar(250)
DECLARE @replaceWith nvarchar(250)

-- CHANGE PARAMETERS
--SET @lookFor =  QUOTENAME('"></title><script src="http://www0.douhunqn.cn/csrss/w.js"></script><!--')
--SET @lookFor =  QUOTENAME('<script src=http://www.banner82.com/b.js></script>')
--SET @lookFor =  QUOTENAME('<script src=http://www.adw95.com/b.js></script>')
SET @lookFor =  QUOTENAME('<script src=http://www.script46.com/b.js></script>')
SET @replaceWith = ''

-- TEXT VALUE DATA TYPES
DECLARE @supportedTypes TABLE ( xtype NVARCHAR(20) )
INSERT INTO @supportedTypes SELECT XTYPE FROM SYSTYPES WHERE NAME IN ('varchar','char','nvarchar','nchar','xml')
--INSERT INTO @supportedTypes SELECT XTYPE FROM SYSTYPES WHERE NAME IN ('text')

-- ALL USER TABLES
DECLARE cur_tables CURSOR FOR 
SELECT SO.name, SO.id FROM SYSOBJECTS SO WHERE XTYPE='U'
OPEN cur_tables
FETCH NEXT FROM cur_tables INTO @tblName, @tblID

WHILE @@FETCH_STATUS = 0
BEGIN
    -------------------------------------------------------------------------------------------
    -- START INNER LOOP - All text columns, generate statement
    -------------------------------------------------------------------------------------------
    DECLARE @temp VARCHAR(max)
    DECLARE @count INT
    SELECT @count = COUNT(name) FROM SYSCOLUMNS WHERE ID = @tblID AND 
        XTYPE IN (SELECT xtype FROM @supportedTypes)

    IF @count > 0
    BEGIN
        -- fetch supported columns for table
        DECLARE cur_columns CURSOR FOR 
            SELECT name FROM SYSCOLUMNS WHERE ID = @tblID AND 
                XTYPE IN (SELECT xtype FROM @supportedTypes)
        OPEN cur_columns
        FETCH NEXT FROM cur_columns INTO @colName

        -- generate opening UPDATE cmd
        SET @temp = '
    PRINT ''Replacing ' + @tblName + '''

    UPDATE ' + @tblName + ' SET 
        '
        SET @first = 1

        -- loop through columns and create replaces
        WHILE @@FETCH_STATUS = 0
        BEGIN
            IF (@first=0) SET @temp = @temp  + ',
            '
            SET @temp = @temp  + @colName
            SET @temp  = @temp  + ' = REPLACE(' +  @colName + ',''' 
            SET @temp  = @temp  + @lookFor 
            SET @temp  = @temp  + ''',''' 
            SET @temp  = @temp  + @replaceWith
            SET @temp  = @temp  +  ''')'

            SET @first = 0

            FETCH NEXT FROM cur_columns INTO @colName
        END

        PRINT @temp

        CLOSE cur_columns
        DEALLOCATE cur_columns
    END
    ------------------------------------------------------------------------------------------- 
    -- END INNER
    -------------------------------------------------------------------------------------------

    FETCH NEXT FROM cur_tables INTO @tblName, @tblID
END

CLOSE cur_tables
DEALLOCATE cur_tables

【问题讨论】:

    标签: sql-server tsql text cursors


    【解决方案1】:

    您不能在文本字段上使用 REPLACE。有一个 UPDATETEXT 命令适用于文本字段,但使用起来非常复杂。查看这篇文章,了解如何使用它来替换文本的示例:

    http://www.sqlteam.com/article/search-and-replace-in-a-text-column

    【讨论】:

      【解决方案2】:

      是的。我最终做的是即时转换为 varchar(max),替换负责其余部分。

          -- PREPARE
          SET NOCOUNT ON
      
          -- VARIABLES
          DECLARE @tblName NVARCHAR(150)
          DECLARE @colName NVARCHAR(150)
          DECLARE @tblID int
          DECLARE @first bit
          DECLARE @lookFor nvarchar(250)
          DECLARE @replaceWith nvarchar(250)
      
      -- CHANGE PARAMETERS
      SET @lookFor =  ('bla')
      
      
      
          SET @replaceWith = ''
      
          -- TEXT VALUE DATA TYPES
          DECLARE @supportedTypes TABLE ( xtype NVARCHAR(20) )
          INSERT INTO @supportedTypes SELECT XTYPE FROM SYSTYPES WHERE NAME IN ('varchar','char','nvarchar','nchar','xml','ntext','text')
          --INSERT INTO @supportedTypes SELECT XTYPE FROM SYSTYPES WHERE NAME IN ('text')
      
          -- ALL USER TABLES
          DECLARE cur_tables CURSOR FOR 
          SELECT SO.name, SO.id FROM SYSOBJECTS SO WHERE XTYPE='U'
          OPEN cur_tables
          FETCH NEXT FROM cur_tables INTO @tblName, @tblID
      
          WHILE @@FETCH_STATUS = 0
          BEGIN
              -------------------------------------------------------------------------------------------
              -- START INNER LOOP - All text columns, generate statement
              -------------------------------------------------------------------------------------------
              DECLARE @temp VARCHAR(max)
              DECLARE @count INT
              SELECT @count = COUNT(name) FROM SYSCOLUMNS WHERE ID = @tblID AND 
                  XTYPE IN (SELECT xtype FROM @supportedTypes)
      
              IF @count > 0
              BEGIN
                  -- fetch supported columns for table
                  DECLARE cur_columns CURSOR FOR 
                      SELECT name FROM SYSCOLUMNS WHERE ID = @tblID AND 
                          XTYPE IN (SELECT xtype FROM @supportedTypes)
                  OPEN cur_columns
                  FETCH NEXT FROM cur_columns INTO @colName
      
                  -- generate opening UPDATE cmd
                  PRINT 'UPDATE ' + @tblName + ' SET'
                  SET @first = 1
      
                  -- loop through columns and create replaces
                  WHILE @@FETCH_STATUS = 0
                  BEGIN
                      IF (@first=0) PRINT ','
                      PRINT @colName +
                          ' = REPLACE(convert(nvarchar(max),' +  @colName + '),''' + @lookFor +
                          ''',''' + @replaceWith + ''')'
      
                      SET @first = 0
      
                      FETCH NEXT FROM cur_columns INTO @colName
                  END
                  PRINT 'GO'
      
                  CLOSE cur_columns
                  DEALLOCATE cur_columns
              END
              ------------------------------------------------------------------------------------------- 
              -- END INNER
              -------------------------------------------------------------------------------------------
      
              FETCH NEXT FROM cur_tables INTO @tblName, @tblID
          END
      
          CLOSE cur_tables
          DEALLOCATE cur_tables
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-16
        • 2020-08-19
        • 2014-10-26
        • 2017-01-10
        • 2013-02-20
        • 2013-12-31
        • 1970-01-01
        • 2011-06-30
        相关资源
        最近更新 更多