Showing posts with label Dynamic Lookup. Show all posts
Showing posts with label Dynamic Lookup. Show all posts

Thursday, 16 March 2017

SSIS – Dynamic Lookup Transform

Introduction
Here in this article we are going to discuss about dynamic Lookup Transform, which also means the parameterized Lookup Transform. As a SSIS developer we all are aware about Lookup Transform and how useful it is.

The Lookup Transform Cache plays a very important role in terms to holding the record set of Lookup.

There are three type of Cache mode found in Lookup Transform

    1. Full Cache
    2. Partial Cache
    3. No Cache

If the data source for Lookup is huge nothing work perfectly in terms of performance of SSIS package is concern and sometimes the package fails.

So we have to limit the number of records for Lookup Transform according to our needs and we want to do it dynamically.

To understand it properly here we are taking a simple case scenario.

Case Scenario




We have a simple SSIS package which contains a single Data Flow task. The data flow task retrieve data from a Flat File and store it in a Table Object.

Sample Flat file: EmployeeDetils.txt

EmployeeID;EmployeeName
101;Joydeep Das
102;Sukamal Jana
103;Deepasree Das
104;Deblina Bhattacharya
105;Priya Bannerjee
106;Shipra Roy Chowdhury

…..

Note: Think this flat file have millions of records.

Before storing it in table object we have a Lookup Transform that check the Employee ID into the lookup table and if exists it just same the records into destination table, others discard it.

We have another table object named tbl_Grade

Sample Table Object: tbl_Grade

EmployeeID
Designation
101
A
102
B
103
B
104
A
105
A
106
A

Note: Think that the table object named tbl_Gradealso have millions of records.

So it is not a wise decision to load the entire table into Lookup transform.

So according to our needs, we need a parameterized query in Lookup Transform with Designation. If we specified a designation, the Lookup Transform load those records only.
But we want to provide this Designation value by a variable not hard-coded.

So, it is called a Dynamic Lookup Transform. Hope you understand the case scenario.

So What Solution we can provide
There is two type of solution that we can provide in this scenario.

     1. By using Cache Transform
     2. By using Dynamic Query in Lookup Transform.

Personally, I am not preferring the first approach (By using Cache Transform) as we have to populate the Cache Transform every time with our dynamic SQL statement (When we change the Department value in our variable).

Second one is the good approach. But here in this article we are going to discuss both of them and it’s totally depends on you what you choose as a approach.

Before jumping into solution, let’s take some sample of flat file and Lookup Transform table.

Flat File Sample:




Lookup Transform Table Object definition and Records:

CREATE TABLE [dbo].[tbl_Grade]
  (
    EmployeeID       INT        NOT NULL PRIMARY KEY,
    Designation      CHAR(1)    NOT NULL
  );
GO

INSERT INTO [dbo].[tbl_Grade]
      (EmployeeID, Designation)
VALUES(101, 'A'),(102, 'B'),(103, 'B'),(104, 'A'),
      (105, 'A'),(106, 'A');
GO

SELECT * FROM [dbo].[tbl_Grade];

EmployeeID  Designation
----------- -----------
101         A
102         B
103         B
104         A
105         A
106         A

Solution -1 [By using Cache Transform]





In the above figure we are just storing the Lookup data sets into a Cache Transform.





In OLEDB Source editor we are using Data Access mode as SQL Command and the SQL statement is a parameterized query.

SELECT EmployeeID FROM [dbo].[tbl_Grade] WHERE Designation = ?;

The value of the parameter is supplied by the variable. Here the actual filtration of Lookup Transform occurs.







In Lookup Transform we choose Connection Type as Cache Connection Manager.

Solution – 2 [By using Dynamic Query in Lookup Transform]

Here first we just set a Normal Lookup transform as we set it before.



What we have to do is go to the Control Flow Tab and Select the Property named 
Expression of Data Flow Task.

Data Flow Task à Property à Expression à[Lookup].[SQLCommand]










Expression:

"SELECT EmployeeID FROM [dbo].[tbl_Grade] WHERE Designation ='"+ @[User::v_EmployeeGrade]+"'"


Hope you like it.




Posted by: MR. JOYDEEP DAS

Sunday, 5 February 2017

Comparing Table in Different Database with Dynamic Lookup

Introduction
Here we are trying to compare two Table object in different Server Database. If we search goggle we can find a lot of process to compare two tables in Different server Database. But the Question is both the table have 10M of records.

Comparing two Tables with huge data is not simple, especially when they are in different database.

Common solution we find that to load the Source table into a Temporary table in Destination Database and then compare Temporary Table with Destination Table.

It is so simple? We have to load 10M data into a Temporary Table first and then compare. It may cause a memory related problem and our package stuck.

Another solution is by using Lookup Trans form. Good solution when we think about two different server databases. But if we load 10 M data into a lookup transform ... Only God Knows what happens.

Others we can use Merge Join transform. But Merge join is a Blocking Transform and more it takes two sorted input of data flow by using Sort transform.... Bad Idea.

So What the Solution
There is no pre-defining solution for that. It depends how we design our SSIS package. How we load our data into our SSIS transform.

Here our strategy is by loading data depends on a specified columns. If the columns is a Date data type it is good for us. We can use the date range to load the data. But we must do it by automatic way.

SSIS Solutions
Here we are taking two tables with few records for just an example purpose only. We must assume it with 10 M records.

Step – 1 [ Source and Destination Table Objects ]

Assume that the Data is already migrated from Source to Destination.

CREATE TABLE [dbo].[Emp_Source]
  (
    EmpID       INT        NOT NULL IDENTITY,
EmpGrade   CHAR(1)    NOT NULL,
     DOJ        DATE       NOT NULL
  );

CREATE TABLE [dbo].[Emp_Destination]
  (
    EmpID       INT        NOT NULL IDENTITY,
     EmpGrade   CHAR(1)    NOT NULL,
     DOJ        DATE       NOT NULL
  );

Source and Destination have same data.

EmpID
EmpGrade
DOJ
1
C
2010-01-01
2
C
2010-01-01
3
C
2010-01-01
4
C
2010-01-01
5
C
2011-01-01
6
C
2011-01-01
7
C
2011-01-01
8
C
2011-01-01
9
B
2012-01-01
10
B
2012-01-01
11
B
2012-01-01
12
A
2013-01-01
13
A
2013-01-01
14
A
2013-01-01
15
C
2014-01-01
16
C
2014-01-01
17
C
2014-01-01
18
C
2015-01-01
19
C
2015-01-01
20
C
2015-01-01
21
C
2016-01-01
22
B
2017-01-01
23
B
2017-01-01
24
B
2017-01-01

Step – 2 [ Now Create a Segment Table for Limited Data Load in SSIS Package ]
EmpID
EmpGrade
DOJ
Segment
1
C
2010-01-01
Segment-1
2
C
2010-01-01
3
C
2010-01-01
4
C
2010-01-01
Segment-2
5
C
2011-01-01
6
C
2011-01-01
7
C
2011-01-01
8
C
2011-01-01
9
B
2012-01-01
Segment-3
10
B
2012-01-01
11
B
2012-01-01
12
A
2013-01-01
Segment-4
13
A
2013-01-01
14
A
2013-01-01
15
C
2014-01-01
Segment-5
16
C
2014-01-01
17
C
2014-01-01
18
C
2015-01-01
Segement-6
19
C
2015-01-01
20
C
2015-01-01
21
C
2016-01-01
Segment-7
22
B
2017-01-01
Segment-8
23
B
2017-01-01
24
B
2017-01-01

CREATE TABLE [dbo].[tbl_Segment]
  (
     SegmentName          VARCHAR(50)     NOT NULL,
     FromDate             DATE            NOT NULL,
     ToDate               DATE            NOT NULL
  );

INSERT INTO [dbo].[tbl_Segment]
(SegmentName, FromDate, ToDate)
VALUES
('Segment-1', '2010-01-01', '2010-12-31'),
('Segment-1', '2011-01-01', '2011-12-31'),
('Segment-1', '2012-01-01', '2012-12-31'),
('Segment-1', '2013-01-01', '2013-12-31'),
('Segment-1', '2014-01-01', '2014-12-31'),
('Segment-1', '2015-01-01', '2015-12-31'),
('Segment-1', '2016-01-01', '2016-12-31'),
('Segment-1', '2017-01-01', '2017-12-31');

SELECT * FROM [dbo].[tbl_Segment];

SegmentName
FromDate
ToDate
Segment-1
2010-01-01
2010-12-31
Segment-1
2011-01-01
2011-12-31
Segment-1
2012-01-01
2012-12-31
Segment-1
2013-01-01
2013-12-31
Segment-1
2014-01-01
2014-12-31
Segment-1
2015-01-01
2015-12-31
Segment-1
2016-01-01
2016-12-31
Segment-1
2017-01-01
2017-12-31

By using this segmentation table we can load a limited amount of records in SSIS package.

Step – 3 [ SSIS Package Control Flow ]



Step – 4 [ The Variable ]
Name
Data Type
SQL
String
v_FromDT
String
v_ToDT
String
vDateFromTo
Object


Step – 5 [ Execute SQL – Get the Data Range ]






Step – 6 [ ForEach Container ]




Step – 7 [ Set the variable Expression – Variable name SQL ]

The Expression is
"SELECT * FROM [dbo].[Emp_Source] WHERE DOJ BETWEEN '"+  @[User::v_FromDT] +"'  AND  '"+  @[User::v_ToDT]+"'"

Step – 8 [ Data Flow Task ]




Step – 9 [ OLEDB Source Settings ]




Step  - 10 [ The Lookup Transform ]
The main challenge is to create a dynamic Lookup Transform. To do that just creates a tradition lookup transform with OLEDB connection manager that we create normally with SQL Command not directly choosing Table Object.

Now we have to make the Lookup Dynamic and use the same Expression used before.
"SELECT * FROM [dbo].[Emp_Source] WHERE DOJ BETWEEN '"+  @[User::v_FromDT] +"'  AND  '"+  @[User::v_ToDT]+"'"

For that we just select the Data Flow Task where the lookup exists. Select the property of Data Flow Task and choose the Expression. Then set the SQL Command Property by Expression. That’s all












Hope you like it.




Posted by: MR. JOYDEEP DAS