2009-02-03 30 views
7

Tüm veritabanı dizesi alanlarını kırpabileceğim sql sunucusunda (transact-sql aracılığıyla) hızlı bir yol olup olmadığını biliyor musunuz?Tüm veritabanı alanlarını kırpın

+0

Sütunun uzunluğunu, bu sütunun değerinde bulunan maksimum uzunluğa güncellemek mi istediniz?Ben İsim VARCHAR (200) 'dir tablo Kişilerin bir sütun adı olması gibi demek ve 10000 tüm satırları en uzun İsim (23) VARCHAR sütun değiştirmek için 23 mı? –

cevap

19

yok imleçlerini. Çıktıyı kopyalayıp yapıştırın. Ayrıca varchar (max) olmayan SQL 2000 için de çalışır. Bu, istenirse her UPDATE'in sonuna bir GO satırı eklemek için kolayca genişletilebilir.

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

+1. Günümü her şey gibi kurtardı –

13

Sorunuz biraz muğlak, ama peşinde olduğun şey bu mu?

UPDATE mytable SET mycolumn= LTRIM(RTRIM(mycolumn)) 
'Tablom' tablosundaki 'Sütunum' sütununda tüm değerlerden hem ön ve arka boşluk kaldırır

. Güncelleştirme deyimini oluşturarak information_schema.columns ve RTRIM varchar/nvarchar sütunları üzerinde

2

Sadece VARCHAR dize alanları değil, CHAR alanlarını :)

O wouldn üzerinde bir giydirme yapıyoruz emin olun Çok iyi değil. Herkes bir imleç olmadan bunu nasıl biliyorsa

+0

Önde gelen alanlara ne dersiniz? – alyssackwan

+0

Tamam, LTRIM'in bir CHAR sütununda bazı hakları vardır. Sadece RTRIM değil. – BradC

3

, onu gönderin:

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

Bir süre döngü sayısı var;) – AlexCuse

0

teşekkürler çocuklar,

Entaroadun kodu sadece benim requierements için bazı küçük değişiklikler yapmak zorunda, benim için oldukça iyi çalıştı ve aynı zamanda ben her tekrarında @colum_list sıfırlamak zorunda kaldı.

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

- V Hızlı ve Kirli!

- Bu, tek bir tabloda çalıştırılacak kod üretmekse, bu kodu metin çıktısıyla çalıştırın;

@ Tablo nvarchar (100) bildirmek

üzerinde

grubu nocount @ tablo = 'YourTableHere'

SELECT 'UPDATE' + @ Tablo + 'ayarla' seçmek '[' + Column_Name + ' ] = "+ 'LTRIM (RTRIM ([' + Column_Name + '])),' information_schema.columns DAN WHERE Table_Name = @ tablo ve veri_türü BENZER '% CHAR%'

- metin çıktısı olarak çalıştırmak (Query/Results To ... Metin için sonuçlar - Metin çıktısını (son virgül hariç) kopyalayıp yeni bir sorgu penceresine yapıştırın ve çalıştırın.

0

Tamam, bu hızlı ve kirliydi, ancak geçerli bir proje tarafından 'düzgün' - ve hiçbir imleç olmaksızın, ancak biraz sql birleştirme hilesiyle yeterince motive oldum.

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

veritabanındaki tüm tabloları kullanmak Dan cevabını Güncelleme: olsa dinamik sql kullanıyor mu. Sadece snippet'i çalıştırın ve yürütmek için sonucu kopyalayın.

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