Выражение SSIS для обработки значений NULL в нескольких столбцах - PullRequest
3 голосов
/ 06 августа 2020

У меня есть источник OLE DB с некоторыми значениями NULL, в нем 50 столбцов, и я пытаюсь извлечь строки, которые имеют NULLs в недопустимое место назначения данных, выражение, которое у меня было для условного разделения, -

ISNULL([StudentName]) == TRUE

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

Ответы [ 5 ]

1 голос
/ 08 августа 2020

Самое простое решение (я не уверен, рекомендуется ли это с точки зрения производительности) - использовать команду SQL в источнике OLE DB, где вы должны добавить новый столбец, который является объединением все столбцы. Затем вы должны использовать этот столбец в условном разбиении вместо упоминания всех столбцов. Например:

SELECT *, [Column1] + [Column2] + [Column3] as [CheckColumn]
FROM [Table]
1 голос
/ 07 августа 2020

Хотите верьте, хотите нет, это меня озадачивает с тех пор, как вы его разместили.

Я не нашел способа сделать это SSIS, но вот возможное решение с использованием источника компонента сценария. Это найдет все ключи, связанные со строкой, которая имеет хотя бы один нулевой столбец.

    DataTable dt = new DataTable();

    string sql = "Enter your extract SQL here";
    using(OleDbConnection conn = new OleDbConnection("Data Source=XXXXXXXXX;Initial Catalog=YYYYY;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"))
    {
        using (OleDbCommand cmd = new OleDbCommand(sql,conn))
        {
            cmd.CommandType = CommandType.Text;
            conn.Open();
            dt.Load(cmd.ExecuteReader());
        }
    }

    foreach (DataRow row in dt.Rows)
    {
        foreach (DataColumn col in dt.Columns)
        {
            if (row[col] == DBNull.Value)
            {
                Output0Buffer.AddRow();
                Output0Buffer.NullRowKey = row.Field<int>(0); //This is the 0 based index of the key in the data
                break;
            }
        }
    }

Проблема, с которой я столкнулся, заключалась в попытке использовать столбцы в типе данных Output0Buffer, который вы должны использовать при использовании компонента сценария преобразования. Мне действительно нужно использовать источник компонента скрипта и загрузить данные в таблицу данных, чтобы иметь доступ к свойству Columns.

0 голосов
/ 11 августа 2020

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

если 50 столбцов не находятся в конкретной таблице, просто создайте таблицу tmp со всеми столбцами, которые вам нужны (выберите ..... в #tmp из ....)

Затем сгенерируйте условие.

declare @schema sysname = 'Purchasing'
declare @table sysname = 'PurchaseOrders'
        
;with cols as (
        select  convert(varchar(max), 'ISNULL(' + QUOTENAME(column_name) + ') == TRUE') as col, TABLE_SCHEMA, TABLE_NAME, ordinal_position 
        from INFORMATION_SCHEMA.COLUMNS 
        where TABLE_SCHEMA = @schema and TABLE_NAME = @table and ORDINAL_POSITION = 1
        union all
        select CONVERT (varchar(max) , cl.col + ' || ISNULL(' + QUOTENAME(column_name) + ') == TRUE') as col, c.TABLE_SCHEMA, c.TABLE_NAME, c.ordinal_position 
        from INFORMATION_SCHEMA.COLUMNS c
        inner join cols cl on cl.TABLE_SCHEMA = c.TABLE_SCHEMA and cl.TABLE_NAME = c.TABLE_NAME and c.ORDINAL_POSITION = cl.ORDINAL_POSITION + 1
    )
    select '= ' + cols.col 
    from cols
    where ORDINAL_POSITION = (select MAX(ordinal_position) from cols)

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

= ISNULL([PurchaseOrderID]) == TRUE || ISNULL([SupplierID]) == TRUE || ISNULL([OrderDate]) == TRUE || ISNULL([DeliveryMethodID]) == TRUE || ISNULL([ContactPersonID]) == TRUE || ISNULL([ExpectedDeliveryDate]) == TRUE || ISNULL([SupplierReference]) == TRUE || ISNULL([IsOrderFinalized]) == TRUE || ISNULL([Comments]) == TRUE || ISNULL([InternalComments]) == TRUE || ISNULL([LastEditedBy]) == TRUE || ISNULL([LastEditedWhen]) == TRUE

Но будьте осторожны, независимо от того, какой метод вы выберете (мой или создание условия с помощью Excel), тестирование 50 столбцов в SSIS может привести к огромному переполнению, особенно если у вас много строк.

Лучшей альтернативой было бы поставить флажок в каждой строке в наборе данных и отфильтровать / перенаправить, установлен ли «HasNullValues» или нет.

0 голосов
/ 11 августа 2020

Вот совершенно другое решение, использующее уже сформированное условное разделение:

ISNULL([StudentName])

Вы можете создать тест ИЛИ в Excel, вставив список столбцов (я получаю это из метаданных в данных линия тока). Обычно я использую этот метод для построения целевой таблицы.

Вставить в Excel и получить имена столбцов в столбце A.

Введите эту формулу в ColB:

="ISNULL("&A1&")||"

Введите эту формулу непосредственно в B2:

=B1&"ISNULL("&A2&")||"

Это должно привести к следующему результату в B2:

ISNULL(Col1)||ISNULL(Col2)||

Теперь перетащите B2 в конец списка (в вашем случае B50).

B50 теперь будет содержать вашу окончательную формулу для условного разделения:

ISNULL(Col1)||ISNULL(Col2)||ISNULL(Col3)||ISNULL(Col4)||ISNULL(Col5)||ISNULL(Col6)||ISNULL(Col7)||ISNULL(Col8)||ISNULL(Col9)||ISNULL(Col10)||ISNULL(Col11)||ISNULL(Col12)||ISNULL(Col13)||ISNULL(Col14)||ISNULL(Col15)||ISNULL(Col16)||ISNULL(Col17)||ISNULL(Col18)||ISNULL(Col19)||ISNULL(Col20)||ISNULL(Col21)||ISNULL(Col22)||ISNULL(Col23)||ISNULL(Col24)||ISNULL(Col25)||ISNULL(Col26)||ISNULL(Col27)||ISNULL(Col28)||ISNULL(Col29)||ISNULL(Col30)||ISNULL(Col31)||ISNULL(Col32)||ISNULL(Col33)||ISNULL(Col34)||ISNULL(Col35)||ISNULL(Col36)||ISNULL(Col37)||ISNULL(Col38)||ISNULL(Col39)||ISNULL(Col40)||ISNULL(Col41)||ISNULL(Col42)||ISNULL(Col43)||ISNULL(Col44)||ISNULL(Col45)||ISNULL(Col46)||ISNULL(Col47)||ISNULL(Col48)||ISNULL(Col49)||ISNULL(Col50)||

Просто удалите последнюю ||.

0 голосов
/ 09 августа 2020

Непонятно, имели ли вы в виду данные bad, когда ALL столбцы NULL или только ANY столбец NULL.

Если это ALL, то вы можете сделайте это:

COALESCE(col1, col2, col3, .....) IS NULL

Если это 'ЛЮБОЙ', то вы можете сделать следующее:

(col1 + col2 + col3 + .....) IS NULL

В BOTH случаях:

вам понадобится для преобразования нестроковых столбцов (numeri c, date, et c) в строку через CONVERT(varchar(8000), col)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...