2016-09-27 3 views
3

У меня есть следующие содержимое файла CSVУдаление разделителей из одного столбца в файл CSV без открытия файла

Вот содержимое файла CSV:

Date_Added|this_flag|Name|DOB|SSN|ID 

1 мая 2015 | Y | Jingle | heimerscmidt | 19901002 | 123456789 | 3

May 1st, 2015|N|Jingleheimerscmidt|19901002|123456789|3 
May 5th, 2015|Y|Jon|19901001||1 
May 1st, 2015|N|Jon|19901002||1 
May 1st, 2015|Y|Jacob|19901001|234567890|2 
May 5th, 2015|N|Jingleheimerscmidt|19901001|123456789|3 
May 1st, 2015|Y|Jingleheimerscmidt|19901001|123456789|3 

Как вы можете видеть в смелом и курсивном содержании, есть оператор трубы в содержании кроме оператора трубы отдела юта columns.I хотят удалите этот оператор трубы из текста, не открывая файл csv. Есть ли способ решить эту проблему, написав код или любой другой подход.

+0

без открытия файла? Вы имеете в виду, не открывая в текстовом редакторе, чтобы сделать это вручную? Файл должен быть открыт, чтобы прочитать его содержимое. Вы можете привести его как одно значение VARCHAR и вырезать строку на основе ваших собственных правил ... например, разбивать каждый столбец на несколько строк и определять, когда существует слишком много строк, а затем конкатенация строк и поворот назад в табличный формат – Matt

+1

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

+0

Независимо от этого, вы должны открыть файл, чтобы изменить его - либо с помощью кода, либо вручную. – Missy

ответ

0

okay Я знаю, что вы отметили oracle, поэтому, возможно, вы сами или другой Гуру Oracle может перенести это решение с SQL-сервера. Я знаю, что оракул способен на каждую из этих операций.

Обычно я бы сказал, что вам нужен быстрый/фантастический способ разделения строки, но в этом случае вам нужно поддерживать порядковое положение строк между разделителями. Поэтому я подумал о том, как вы могли бы это сделать.

1) Сначала импортируйте CSV в таблицу темп как все 1 столбец. теперь это будет проблемой, если ваш CRLF также находится в столбце Name ... но мы предположим, что это не потому, что вы не указали его.

2) Создайте row_number на этой таблице, чтобы использовать в качестве поддельного первичного ключа, и определите, когда есть больше разделителей, чем должно быть.

3) используйте рекурсивный cte, чтобы пролить строку в строки и сохранить порядковое положение подстроки в исходной строке, с которой позже будет конкатенация.

4) Определить, какие строки к группе путем изменения OrdinalPostion пути MergePositions и генерировании DENSE_RANK() на его основе

5) Условное Агрегирование с использованием OrdinalGroup как номер столбца, а затем использовать метод конкатенации, чтобы объединить все OrdginalGroup 3 ряда.

DECLARE @CSV as TABLE (LumpedColumns NVARCHAR(MAX)) 
INSERT INTO @CSV VALUES 
('May 1st, 2015|Y|Jingle|he|imerscmidt|19901002|123456789|3') 
,('May 1st, 2015|N|Jingleheimerscmidt|19901002|123456789|3') 
,('May 5th, 2015|Y|Jon|19901001||1') 
,('May 1st, 2015|N|Jon|19901002||1') 
,('May 1st, 2015|Y|Jacob|19901001|234567890|2') 
,('May 5th, 2015|N|Jingleheimerscmidt|19901001|123456789|3') 
,('May 1st, 2015|Y|Jingleheimerscmidt|19901001|123456789|3') 

;WITH cteFakePrimaryKey AS (
    SELECT 
     LumpedColumns 
     ,CASE WHEN LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) > 5 THEN 
      LEN(LumpedColumns) - LEN(REPLACE(LumpedColumns,'|','')) - 5 ELSE 0 END as MergeXPositions 
     ,ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as PK 
    FROM 
     @CSV 
) 


, cteRecursive AS (
    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,LEFT(LumpedColumns,CHARINDEX('|',LumpedColumns)-1) as ColValue 
     ,RIGHT(LumpedColumns,LEN(LumpedColumns) - CHARINDEX('|',LumpedColumns)) as Remaining 
     ,1 As OrdinalPosition 
    FROM 
     cteFakePrimaryKey 

    UNION ALL 

    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,LEFT(Remaining,CHARINDEX('|',Remaining)-1) 
     ,RIGHT(Remaining,LEN(Remaining) - CHARINDEX('|',Remaining)) 
     ,OrdinalPosition + 1 
    FROM 
     cteRecursive 
    WHERE 
     Remaining IS NOT NULL AND CHARINDEX('|',Remaining) > 0 

    UNION ALL 

    SELECT 
     PK 
     ,LumpedColumns 
     ,MergeXPositions 
     ,Remaining 
     ,NULL 
     ,OrdinalPosition + 1 
    FROM 
     cteRecursive 
    WHERE Remaining IS NOT NULL AND CHARINDEX('|',Remaining) = 0 
) 

, cteOrdinalGroup AS (
    SELECT 
     PK 
     ,LumpedColumns 
     ,ColValue 
     ,OrdinalPosition 
     ,DENSE_RANK() OVER (PARTITION BY PK ORDER BY 
      CASE 
      WHEN OrdinalPosition < 3 THEN OrdinalPosition 
      WHEN OrdinalPosition > (3 + MergeXPositions) THEN OrdinalPosition 
      ELSE 3 END) as OrdinalGRoup 

    FROM 
     cteRecursive 
) 

SELECT 
    PK 
    ,LumpedColumns 
    ,MAX(CASE WHEN OrdinalGRoup = 1 THEN ColValue END) as Date_Added 
    ,MAX(CASE WHEN OrdinalGRoup = 2 THEN ColValue END) as this_flag 
    ,STUFF(
     (SELECT '|' + ColValue 
     FROM 
      cteOrdinalGroup g2 
     WHERE 
      g1.PK = g2.PK 
      AND g2.OrdinalGroup = 3 
     ORDER BY 
      g2.OrdinalPosition 
     FOR XML PATH('')) 
     ,1,1,'') as name 
    ,MAX(CASE WHEN OrdinalGRoup = 4 THEN ColValue END) as DOB 
    ,MAX(CASE WHEN OrdinalGRoup = 5 THEN ColValue END) as SSN 
    ,MAX(CASE WHEN OrdinalGRoup = 6 THEN ColValue END) as ID 
FROM 
    cteOrdinalGroup g1 
GROUP BY 
    PK 
    ,LumpedColumns 
ORDER BY 
    PK 
0

Если это только один случай, вам нужно работать, и вы не хотите, чтобы изменить файл, и вы должны сделать это в Informatica, вы можете изменить свойство Input Type сеанса для этого Source Qualifier от File к Command и использовать СЭД, чтобы сделать замену, как:

cat $$FileName | sed -e 's/Jingle|heimerscmidt/Jingleheimerscmidt/g' 

это не очень хорошее решение, следовательно, это не общий один. Но, возможно, это сделает или, по крайней мере, даст вам некоторые идеи.

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

  • Нет связанных вопросов^_^