2014-10-11 3 views
0

У меня есть столбец в таблице sql server, в которой имя термина - это данные. Мне нужно разделить имя сервера на два столбца. Имя хоста входит в один столбец, а имя экземпляра входит в другой столбец. Любая помощь будет оценена по достоинству.Разделите строку в столбце на несколько столбцов, используя ssis

Хотелось бы использовать ssis для этой цели.

пример: -

Input      Expected Output 

column1      Column2   Column3 

ServerName     Hostname   InstanceName 

wsql1005x\Express   wsql1005x   Express 

ответ

1

Есть два доступных для вас маршруты. Вы можете использовать компонент скрипта или использовать задачу Derived Column и выражения там. Это решение использует этот подход.

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

Это решение не ручка, разделяющая потенциально нулевую колонку. Поскольку исходные данные не должны допускать этого, я не хотел бы еще больше усложнять решение. Этот подход делает обрабатывает значение по умолчанию, unnamed, instance.

NVARCHAR (макс)

Вы выбрали для хранения имя сервера и экземпляр в (макс) поле NVARCHAR. Если у вас нет причин для необходимости использования более 4000 символов, вы не только теряете пространство и теряете оптимизатор, тем больете для SSIS.

SSIS получает свою энергию от работы с данными в памяти. Он выделяет память на основе максимального размера для данного столбца. За исключением больших типов объектов, LOB, которые идентифицируются типами данных DT_TEXT, DT_NTEXT, DT_IMAGE. Те, что движок не может выделить достаточную память, и поэтому переносит указатель в память на файл на диске, который представляет эти данные. Диск медленный, поэтому, если вы пытаетесь получить хорошую производительность, теперь вы знаете, почему вы его не получаете.

Трюк заключается в том, чтобы получить ваши данные из типа LOB и во что-то разумное. Какова максимальная длина имени компьютера? Ну, полное доменное имя ограничено 255 байтами, а имя экземпляра ограничено 16. Не нужно переходить на maths.stackexchange.com, чтобы увидеть, что вы превысили максимальную длину в 10 раз.

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

SELECT 'wsql1005x\Express' AS ServerName 
UNION ALL 
SELECT 'localhost' 
UNION ALL 
SELECT @@ServerName; 

Я хотел бы написать его с помощью явного приведения к моей максимально возможной длине

SELECT 
    (D.ServerName AS nvarchar(542)) AS ServerName 
FROM 
(
    SELECT 'wsql1005x\Express' AS ServerName 
    UNION ALL 
    SELECT 'localhost' 
    UNION ALL 
    SELECT @@ServerName 
) D(ServerName); 

Некоторые полезные SO вопросов, охватывающих темы

На с шоу

DER Найти TokenPosition

Целью данного компонента является найти, где наш маркер. Поскольку символ \ также является символом escape, мы должны использовать двойную обратную косую черту, где мы действительно имеем в виду только один символ.

На английском языке это выражение смотрит, существует ли обратная косая черта в столбце ServerName. Если да, то мы сохраним позицию в новом столбце под названием TokenLocation. Если он не существует, то мы укажем, что токеном является конечная позиция строки. Это позволит нам отрезать имя сервера, если экземпляр отсутствует.

TokenLocation

FINDSTRING(ServerName,"\\",1) > 0 ? FINDSTRING(ServerName,"\\",1) : LEN(ServerName) 

DER EndOfFirstWord

Здесь мы определим конечную границу первого слова и начальной границы второго слова. Если значение местоположения маркера совпадает с общей длиной строки, то мы знаем, что в нашей строке нет символа обратной косой черты. Затем мы смотрим одну позицию символа слева и справа от маркера, чтобы идентифицировать наши остановки и начать границы. Для слов без токенов мы поставим обе эти позиции в конец слова.

EndOfFirstWord

(TokenLocation != LEN(ServerName)) ? TokenLocation - 1 : LEN(ServerName) 

BeginOfSecondWord

(TokenLocation != LEN(ServerName)) ? TokenLocation + 1 : LEN(ServerName) 

DER Сформировать новые столбцы

На данный момент мы знаем,

  • где наш маркер TokenLocation
  • , где начинается первое слово (положение 1)
  • , где первые концы слово (EndOfFirstWord)
  • , где второе слово начинается (BeginOfSecondWord)
  • где второе слово заканчивается (LEN(TokenLocation))

, так что это просто вопрос обрезки нашей колонны.

HostName

SUBSTRING(ServerName,1,EndOfFirstWord) 

InstanceName

SUBSTRING(ServerName,BeginOfSecondWord,LEN(ServerName) - TokenLocation) 

enter image description here

+0

Благодарим Вас за решение. Ниже приведена ошибка msg. Я получаю TITLE: Microsoft Visual Studio ------------------------------ Ошибка при потоке данных Задача [Производная колонка [39]]: Функция «FINDSTRING» не поддерживает тип данных «DT_NTEXT» для параметра номер 1. Тип параметра не может быть неявно введен в совместимый тип для функции. Чтобы выполнить эту операцию, операнд должен быть явно выбран оператором литья. – Bunty

+0

Каков тип данных из исходной таблицы. Измените свой вопрос с помощью определения исходной таблицы. Использовать мой исходный запрос, дает ли он ожидаемые результаты? – billinkc

+0

Тип таблицы исходных данных - nvarchar (max) – Bunty

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