Do you know if there\'s a quick way in sql server (via transact-sql) that I could trim all the database string fields.
No cursors. Copy and paste the output. Works also for SQL 2000, which doesn't have varchar(max). This can be easily extended to add a GO line to the end of each UPDATE if desired.
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
-- V Quick and Dirty !
-- If this is to generate code to run on a single table, run this code with text output ;
set nocount on
declare @table nvarchar(100) select @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%'
-- Run as text output (Query/Results To... Results To Text -- Copy and paste the text output (excluding the last comma) into a new query window, and run it .
If anyone knows how to do this without a cursor, please post it:
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