2015-01-27 3 views
0

Я получаю «неожиданный» результат с запросом на обновление в SQL Server 2012. Это то, что я пытаюсь сделать.Неожиданное выполнение запроса на обновление в SQL

Из колонки (Identifier), составленной в ID ','name (например, 258967, Сара Джонс), я должен заполнить другие два столбца: ID и SELLER_NAME.

Оригинальный столбец имеет несколько значений с пустым в конце, а остальные с вне его:

'258967,Sarah Jones' 
'98745,Richard James ' 

Это запрос на обновление, что я выполнения:

UPDATE SELLER 
SET 
IDENTIFIER = LTRIM(RTRIM(IDENTIFIER)), 
ID = Left(IDENTIFIER , charindex(',', IDENTIFIER)-1), 
SELLER_NAME = UPPER(RIGHT((IDENTIFIER),LEN(IDENTIFIER)-CHARINDEX(',',IDENTIFIER))); 

Но я неверный результат в конце

258967,Sarah Jones 258967 SARAH JONES 
98745,Richard James 98745 ICHARD JAMES 

То же самое происходит со всеми именами, которые имеют пробел в en д. На данный момент мне интересно, если бы я указал, что хочу уничтожить все пробелы в начале и в конце значения IDENTIFIER в качестве первого действия, почему система обновляет идентификатор и SELLER_NAMES, а затем делает это действие ?.

Только для указания: Столбец IDENTIFIER является частью таблицы продавца, которая обновляется от другого лица, которое импортирует данные из файла Excel. Я получаю эти значения, и мне нужно нормализовать информацию. Я только могу прочитать таблицу ПРОДАВЦА, учтите это перед ответом

+5

Это то, что вы получаете за паршивый дизайн стола. Если ваш дизайн был правильно нормализован, каждое из этих значений будет иметь свое собственное поле, и вы не будете застревать, пытаясь обновить значения с помощью строковых операций. подумайте, насколько проще было бы «обновить имя продавца set = 'fred', где name = 'sarah'', чем весь этот мусор charindex/len/right. –

+0

Что-то, о чем вы нам не говорите. Нет никакого способа, чтобы «Richar» в «98745, Richar James» трансформировался вашим кодом во что-либо, содержащее подстроку «ICHARD» –

+0

Получите те же результаты, если вы выполняете 'SET IDENTIFIER = LTRIM (RTRIM (IDENTIFIER) 'сначала в отдельном обновлении, а затем установить' ID' и 'SELLER_NAME'?Я думаю, что столбец «IDENTIFIER» может иметь конечное пространство при установке «SELLER_NAME» и что это может испортить разбор. –

ответ

4

Попробуйте это, потому что у вас есть пространство в правой части имени, поэтому оно просто обрезает один символ из имени. Так что просто нужно RTRIM(IDENTIFIER) и вот оно.

SELLER_NAME = UPPER(RIGHT((RTRIM(IDENTIFIER)),LEN(IDENTIFIER)-CHARINDEX(',',IDENTIFIER))); 
+0

Вот почему я сделал эту операцию с IDENTIFIER. Тем не менее, у меня все еще есть те же сомнения: почему LTRIM (RTRIM()) не выполняется раньше, чтобы обновить два других столбца? – d2907

+1

До завершения операции UPDATE у вас нет обновленного значения IDENTIFIER для использования, поэтому LTRIM (RTRIM()) не установил значение. Либо вы должны использовать два отдельных запроса для этого, сначала обновите IDENTIFIER, затем ОБНОВЛЯЙТЕ другие два столбца – HaveNoDisplayName

0

попробовать подрезать IDENTIFIER первый как этот

SALLER_NAME = UPPER(RIGHT((RTRIM(IDENTIFIER),LEN(IDENTIFIER)-CHARINDEX(',',IDENTIFIER))); 
+0

В MSSQL до 2014 нет функции TRIM(). Версия – HaveNoDisplayName

+0

Твой права. изм. – shudima

+0

Я добавил разъяснение в вопросе. однако у меня все еще есть те же сомнения: почему LTRIM (RTRIM()) не выполняется раньше, чтобы обновить два других столбца? – d2907

1

Конструкция таблиц нарушающего 1nf и ничего, кроме болезненной. Вместо того, чтобы делать все эти сумасшедшие манипуляции с строками, вы можете легко использовать PARSENAME здесь.

with Something(SomeValue) as 
(
    select '258967,Sarah Jones' union all 
    select '98745,Richard James ' 
) 

select * 
    , ltrim(rtrim(PARSENAME(replace(SomeValue, ',', '.'), 2))) 
    , ltrim(rtrim(PARSENAME(replace(SomeValue, ',', '.'), 1))) 
from Something 
+0

+1 Хорошее использование ParseName! Единственное предостережение для OP заключается в том, что если имя человека содержит период, например. «Доктор Джонс» это не сработает. – gvee

+0

Я добавил уточнение в вопросе. Тем не менее, у меня все еще есть те же сомнения: почему LTRIM (RTRIM()) не выполняется раньше, чтобы обновить два других столбца? – d2907

+0

Согласился на наличие существующих запятых в названии, конечно, исходный запрос также не учитывал это. Было бы достаточно легко сделать пару дополнительных заметок, чтобы поменять их. –

0

Вместо использования Right() используйте SubString().

Вот пример. Я пытался показать каждый шаг индивидуально для иллюстрации

; WITH x (identifier) AS (
    SELECT '258967,Sarah Jones' 
    UNION ALL 
    SELECT '98745,Richar James ' 
) 
SELECT identifier 
    , CharIndex(',', identifier) As comma 
    , SubString(identifier, CharIndex(',', identifier) + 1, 1000) As name_only 
    , LTrim(RTrim(SubString(identifier, CharIndex(',', identifier) + 1, 1000))) As trimmed_name_only 
FROM x 

Следует отметить, что используемый 1000 должна быть максимальная длина определения столбца или выше, например, если столбец IDENTIFIER равен varchar(2000), тогда вместо этого используйте 2000 экземпляров.

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