修剪所有数据库字段

时间:2009-02-03 16:36:27

标签: sql-server tsql

你知道在sql server中有一个快速的方法(通过transact-sql)我可以修剪所有的数据库字符串字段。

9 个答案:

答案 0 :(得分:19)

没有游标。复制并粘贴输出。也适用于SQL 2000,它没有varchar(max)。如果需要,可以很容易地将其扩展为在每个UPDATE的末尾添加GO行。

SELECT  SQL
FROM    (       SELECT  t.TABLE_CATALOG
                 ,      t.TABLE_SCHEMA
                 ,      t.TABLE_NAME
                 ,      0               SORT
                 ,      'UPDATE  ' + QUOTENAME(t.TABLE_CATALOG) + '.' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME)       SQL
                FROM    INFORMATION_SCHEMA.TABLES       t
                 JOIN   INFORMATION_SCHEMA.COLUMNS      c
                  ON    t.TABLE_CATALOG = c.TABLE_CATALOG
                   AND  t.TABLE_SCHEMA  = c.TABLE_SCHEMA
                   AND  t.TABLE_NAME    = c.TABLE_NAME
                WHERE   t.TABLE_TYPE    = 'BASE TABLE'
                 AND    c.DATA_TYPE     IN ('char','nchar','varchar','nvarchar')
                GROUP BY        t.TABLE_CATALOG
                 ,              t.TABLE_SCHEMA
                 ,              t.TABLE_NAME
                UNION ALL
                SELECT  x.TABLE_CATALOG
                 ,      x.TABLE_SCHEMA
                 ,      x.TABLE_NAME
                 ,      CASE    WHEN    x.COLUMN_NAME_MIN       = y.COLUMN_NAME
                                THEN    1
                                ELSE    2
                        END                                                     SORT
                 ,      CASE    WHEN    x.COLUMN_NAME_MIN       = y.COLUMN_NAME
                                THEN    'SET     '
                                ELSE    ' ,      '
                        END + y.SQL                                             SQL
                FROM    (       SELECT  t.TABLE_CATALOG
                                 ,      t.TABLE_SCHEMA
                                 ,      t.TABLE_NAME
                                 ,      MIN(c.COLUMN_NAME)      COLUMN_NAME_MIN
                                FROM    INFORMATION_SCHEMA.TABLES       t
                                 JOIN   INFORMATION_SCHEMA.COLUMNS      c
                                  ON    t.TABLE_CATALOG = c.TABLE_CATALOG
                                   AND  t.TABLE_SCHEMA  = c.TABLE_SCHEMA
                                   AND  t.TABLE_NAME    = c.TABLE_NAME
                                WHERE   t.TABLE_TYPE    = 'BASE TABLE'
                                 AND    c.DATA_TYPE     IN ('char','nchar','varchar','nvarchar')
                                GROUP BY        t.TABLE_CATALOG
                                 ,              t.TABLE_SCHEMA
                                 ,              t.TABLE_NAME
                        )       x
                 JOIN   (       SELECT  t.TABLE_CATALOG
                                 ,      t.TABLE_SCHEMA
                                 ,      t.TABLE_NAME
                                 ,      c.COLUMN_NAME
                                 ,      QUOTENAME(c.COLUMN_NAME) + ' = LTRIM(RTRIM(' + QUOTENAME(c.COLUMN_NAME) + '))'  SQL
                                FROM    INFORMATION_SCHEMA.TABLES       t
                                 JOIN   INFORMATION_SCHEMA.COLUMNS      c
                                  ON    t.TABLE_CATALOG = c.TABLE_CATALOG
                                   AND  t.TABLE_SCHEMA  = c.TABLE_SCHEMA
                                   AND  t.TABLE_NAME    = c.TABLE_NAME
                                WHERE   t.TABLE_TYPE    = 'BASE TABLE'
                                 AND    c.DATA_TYPE     IN ('char','nchar','varchar','nvarchar')
                        )       y
                  ON    x.TABLE_CATALOG = y.TABLE_CATALOG
                   AND  x.TABLE_SCHEMA  = y.TABLE_SCHEMA
                   AND  x.TABLE_NAME    = y.TABLE_NAME
        )       x
ORDER BY        x.TABLE_CATALOG
 ,              x.TABLE_SCHEMA
 ,              x.TABLE_NAME
 ,              x.SORT
 ,              x.SQL

答案 1 :(得分:13)

你的问题有点模糊,但这就是你追求的目标吗?

UPDATE mytable SET mycolumn= LTRIM(RTRIM(mycolumn))

这将删除'mytable'表中'mycolumn'列中所有值的前导和尾随空格。

答案 2 :(得分:3)

通过动态创建更新语句来遍历information_schema.columns和RTRIM varchar / nvarchar列

答案 3 :(得分:3)

如果有人知道如何在没有光标的情况下执行此操作,请发布:

DECLARE @CRLF AS varchar(2)
SET @CRLF = CHAR(13) + CHAR(10)
DECLARE @TAB AS varchar(1)
SET @TAB = CHAR(9)

DECLARE @template AS varchar(max)
SET @template = 'UPDATE {@OBJECT_NAME}' + @CRLF + 'SET {@column_list}'

DECLARE c CURSOR FAST_FORWARD
    FOR SELECT  DISTINCT
                QUOTENAME(T.TABLE_CATALOG) + '.' + QUOTENAME(T.TABLE_SCHEMA)
                + '.' + QUOTENAME(T.TABLE_NAME) AS [OBJECT_NAME]
        FROM    INFORMATION_SCHEMA.TABLES AS T
        INNER JOIN INFORMATION_SCHEMA.COLUMNS AS C
                ON T.TABLE_CATALOG = C.TABLE_CATALOG
                   AND T.TABLE_SCHEMA = C.TABLE_SCHEMA
                   AND T.TABLE_NAME = C.TABLE_NAME
                   AND T.TABLE_TYPE = 'BASE TABLE'
                   AND C.DATA_TYPE IN ('varchar', 'nvarchar')
        ORDER BY 1

DECLARE @OBJECT_NAME AS sysname

OPEN c

FETCH NEXT FROM c INTO @OBJECT_NAME
WHILE @@FETCH_STATUS = 0
    BEGIN 
        DECLARE @column_list AS varchar(max)
        SELECT  @column_list = COALESCE(@column_list + @CRLF + @TAB + ',', '')
                + QUOTENAME(C.COLUMN_NAME) + ' = LTRIM(RTRIM('
                + QUOTENAME(C.COLUMN_NAME) + '))'
        FROM    INFORMATION_SCHEMA.COLUMNS AS C
        WHERE   C.DATA_TYPE IN ('varchar', 'nvarchar')
                AND QUOTENAME(C.TABLE_CATALOG) + '.'
                + QUOTENAME(C.TABLE_SCHEMA) + '.' + QUOTENAME(C.TABLE_NAME) = @OBJECT_NAME
        ORDER BY C.ORDINAL_POSITION

        PRINT REPLACE(REPLACE(@template, '{@column_list}', @column_list),
                      '{@OBJECT_NAME}', @OBJECT_NAME)

        FETCH NEXT FROM c INTO @OBJECT_NAME
    END

CLOSE c

DEALLOCATE c

答案 4 :(得分:2)

确保在VARCHAR字符串字段而不是CHAR字段上进行修剪:)

那不会有太大的好处。

答案 5 :(得分:1)

更新了dan的答案以使用数据库中的所有表。只需运行代码段并将结果复制即可执行。

SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] SET [' + Column_Name + '] = ' + 'LTRIM(RTRIM([' + Column_Name + ']))' 
FROM INFORMATION_SCHEMA.Columns c
WHERE Data_Type LIKE '%CHAR%'

答案 6 :(得分:0)

谢谢你们,

Entaroadun代码对我来说效果很好,我只需要对我的需求进行一些小改动,而且每次迭代我都必须重置@colum_list。

...
  PRINT REPLACE(REPLACE(@template, '{@column_list}', @column_list),
                          '{@OBJECT_NAME}', @OBJECT_NAME)
    PRINT 'GO'
    SELECT  @column_list = null
            FETCH NEXT FROM c INTO @OBJECT_NAME
...

答案 7 :(得分:0)

- V Quick and Dirty!

- 如果要生成在单个表上运行的代码,请使用文本输出运行此代码;

上设置nocount

声明@table nvarchar(100) 选择@table ='YourTableHere'

SELECT'UPDATE'+ @table +'SET' SELECT'['+ Column_Name +'] ='+'LTRIM(RTRIM(['+ Column_Name +'])),' FROM INFORMATION_SCHEMA.Columns WHERE Table_Name = @table    AND Data_Type LIKE'%CHAR%'

- 作为文本输出运行(查询/结果到...结果到文本 - 将文本输出(不包括最后一个逗号)复制并粘贴到新的查询窗口中,然后运行它。

答案 8 :(得分:0)

好吧,这很快又很脏但是我已经充分激励了当前的项目'正确' - 而且没有游标,但是有点sql连接技巧。 是否使用动态SQL:

--exec    spGenerateTrimStatements 'StaticImportMaturities'
ALTER   PROCEDURE       spGenerateTrimStatements
    (
            @TableName NVARCHAR(100)
    )
AS
    DECLARE @Cr char(2),    
                    @OutputString nvarchar(max)

    SELECT  @Cr = CHAR(13) + CHAR(10)
    SET     NOCOUNT ON

    -- Create table to store commands
    CREATE  TABLE   #tOutput(OutputText nvarchar(500), RowID int identity(1,1))

    -- Build up commands
    INSERT  #tOutput(OutputText)
    SELECT  'UPDATE ' + @TableName + ' SET ' 

    INSERT  #tOutput(OutputText)
    SELECT  '[' + Column_Name + '] = ' + 'LTRIM(RTRIM([' + Column_Name + '])), ' 
    FROM    INFORMATION_SCHEMA.Columns 
    WHERE   Table_Name = @TableName 
       AND Data_Type LIKE '%CHAR%' 

    --      Trim last comma
    UPDATE  #tOutput
    SET             OutputText = LEFT(OutputText, LEN(OutputText)-1)
    WHERE   RowID = (SELECT Max(RowID) FROM #tOutput)

    -- use subselect to concatenate the command string
    SELECT  @OutputString = ISNULL(@OutputString, '') + ISNULL(OutputText, '')
    FROM (SELECT OutputText
          FROM    #tOutput) TextOutput

    -- run the command
    EXEC sp_ExecuteSQL @OutputString