2008-10-08 2 views
3

У меня есть столбец в таблице базы данных (SQL Server 2005), который содержит данные, как это:Прописные первые два символа в столбце таблицы БД

TQ7394 
SZ910284 
T r1534 
su8472 

Я хотел бы обновить этот столбец так что первые два символа имеют верхний регистр. Я также хотел бы удалить любые пробелы между первыми двумя символами. Таким образом, T q1234 станет TQ1234.

Решение должно иметь возможность справиться с несколькими пробелами между первыми двумя символами.

Возможно ли это в T-SQL? Как насчет ANSI-92? Я всегда заинтересован в том, как это делается в других db, поэтому не стесняйтесь публиковать ответы на PostgreSQL, MySQL и др.

+0

Что будет T Q7394 возврат? TQ7394? – Bravax 2008-10-08 12:24:18

+0

Хорошая точка. Также необходимо удалить несколько пространств; Я уточню вопрос. – 2008-10-08 12:27:37

ответ

4

Вот решение:

EDIT:обновление для поддержки замены нескольких пространств между первым и вторым некосмическими символов

/* TEST TABLE */ 
DECLARE @T AS TABLE(code Varchar(20)) 
INSERT INTO @T SELECT 'ab1234x1' UNION SELECT ' ab1234x2' 
     UNION SELECT ' ab1234x3' UNION SELECT 'a b1234x4' 
     UNION SELECT 'a b1234x5' UNION SELECT 'a b1234x6' 
     UNION SELECT 'ab 1234x7' UNION SELECT 'ab 1234x8' 

SELECT * FROM @T 
/* INPUT 
    code 
    -------------------- 
     ab1234x3 
    ab1234x2 
    a b1234x6 
    a b1234x5 
    a b1234x4 
    ab 1234x8 
    ab 1234x7 
    ab1234x1 
*/ 

/* START PROCESSING SECTION */ 
DECLARE @s Varchar(20) 
DECLARE @firstChar INT 
DECLARE @secondChar INT 

UPDATE @T SET 
    @firstChar = PATINDEX('%[^ ]%',code) 
    ,@secondChar = @firstChar + PATINDEX('%[^ ]%', STUFF(code,1, @firstChar,'')) 
    ,@s = STUFF(
      code, 
      1, 
      @secondChar, 
      REPLACE(LEFT(code, 
        @secondChar 
       ),' ','') 
     ) 
    ,@s = STUFF(
      @s, 
      1, 
      2, 
      UPPER(LEFT(@s,2)) 
     ) 
    ,code = @s 
/* END PROCESSING SECTION */ 

SELECT * FROM @T 
/* OUTPUT 
    code 
    -------------------- 
    AB1234x3 
    AB1234x2 
    AB1234x6 
    AB1234x5 
    AB1234x4 
    AB 1234x8 
    AB 1234x7 
    AB1234x1 
*/ 
0
update Table set Column = case when len(rtrim(substring (Column , 1 , 2))) < 2 
      then UPPER(substring (Column , 1 , 1) + substring (Column , 3 , 1)) + substring(Column , 4, len(Column) 
      else UPPER(substring (Column , 1 , 2)) + substring(Column , 3, len(Column) end 

Это работает на том, что если есть пространство, то облицовка той части строки уступит длину меньше, чем 2, поэтому мы разделить строку в три и использовать верхний на 1-е и 3-й символ. Во всех остальных случаях мы можем разделить строку на две части и использовать верхнюю, чтобы первые два символа были в верхнем регистре.

0

Если вы делаете ОБНОВЛЕНИЕ, я бы сделал это за 2 шага; сначала избавиться от пространства (RTrim подстроке), а второй сделать UPPER на первых 2-х символов:

// uses a fixed column length - 20-odd in this case 
UPDATE FOO 
SET bar = RTRIM(SUBSTRING(bar, 1, 2)) + SUBSTRING(bar, 3, 20) 

UPDATE FOO 
SET bar = UPPER(SUBSTRING(bar, 1, 2)) + SUBSTRING(bar, 3, 20) 

Если вам это нужно в SELECT (т.е. инлайн), то я был бы соблазн написать скалярную UDF

+0

Почему бы не использовать REPLACE (bar, '', '') в первом заявлении? Таким образом, если столбец имеет несколько пробелов между первой и второй буквой, вы получите их также. – 2008-10-08 12:21:40

3
UPDATE YourTable 
SET YourColumn = UPPER(
        SUBSTRING(
        REPLACE(YourColumn, ' ', ''), 1, 2 
        ) 
       ) 
       + 
       SUBSTRING(YourColumn, 3, LEN(YourColumn)) 
2

UPPER не собирается повредить какие-либо цифры, поэтому если примеры вы дали вполне репрезентативными, есть на самом деле не никакого вреда в этом:

UPDATE tbl 
SET col = REPLACE(UPPER(col), ' ', '') 
1

Данные примеры только имеет пробелы и в нижнем регистре буквы в начале. Если это справедливо для реальных данных, то просто:

UPPER(REPLACE(YourColumn, ' ', '')) 

Для более конкретного ответа я бы вежливо просить вас расширить ваши спецификации, в противном случае я бы закодировать вокруг все другие возможности (например, значения менее трех символов), не зная, была ли я переоценка моего решения для обработки данных, которые фактически не возникли бы на самом деле :)

Как только вы зафиксировали данные, установите ограничение базы данных, чтобы обеспечить плохие данные не повторяются, например

ALTER TABLE YourTable ADD 
    CONSTRAINT YourColumn__char_pos_1_uppercase_letter 
     CHECK (ASCII(SUBSTRING(YourColumn, 1, 1)) BETWEEN ASCII('A') AND ASCII('Z')); 

    ALTER TABLE YourTable ADD 
    CONSTRAINT YourColumn__char_pos_2_uppercase_letter 
     CHECK (ASCII(SUBSTRING(YourColumn, 2, 1)) BETWEEN ASCII('A') AND ASCII('Z')); 

@ huo73: твоя не работает для меня на SQL Server 2008: Я получаю 'TRr1534' вместо 'TR1534.

Смежные вопросы