Skip to main content
Announcements
Accelerate Your Success: Fuel your data and AI journey with the right services, delivered by our experts. Learn More

STT - Customizing Data with Qlik Replicate

cancel
Showing results for 
Search instead for 
Did you mean: 
Troy_Raney
Digital Support
Digital Support

STT - Customizing Data with Qlik Replicate

Last Update:

Jun 27, 2022 8:10:41 AM

Updated By:

Troy_Raney

Created date:

Jun 27, 2022 8:10:41 AM

Attachments

Troy_Raney_0-1656331715390.gif

 

 

 

Environment

  • Qlik Replicate

 

Transcript

Hello everyone, and welcome to the June edition of Techspert Talks. I’m Troy Raney and I’ll be your host for today's session. Today's presentation is Customizing Data with Qlik Replicate with our own Data Integrations expert, Michael Litz. Michael, why don't you tell us a little bit about yourself?
Oh, hey Troy. Yeah, sure. I work in the Qlik Support group. Replicate is the product I support and I’ve been doing this for about 7, 7-8 years when the company (Attunity at the time) created the product of version 1 (the beta version), and I’ve been there ever since supporting Qlik.
Great. And today, we're gonna be talking about how to transform date fields, source and Target Lookups; we're going to take a look at the difference between table/field versus Global Transformations; and adding some filters to tasks. We're going to demonstrate a lot of that, and talk about what to do when things don't go exactly as planned. Now Michael, for those of us who aren't that familiar, could you just (from a high level) tell us what is a Data Transformation and how does that work with Replicate? What does Replicate do?
Replicate essentially is a tool to copy data from a source to a target database. They're typically different databases; and we do it in near to real time by reading transaction logs from the source; and when we get changes, we move them over to the target in near real time. And Data Transformation is essentially changing the data and or the structure of a table from the source to the target.
So, let's jump into the demo. You prepared an environment with Qlik Replicate November 2021; can you show us how to do a transformation?
Yes. I’m going to start off with the global level, and then I’ll move into a table level transformation.
I’m going to create a brand new task. It's very easy to do that. I’ll just call this SQL.
Okay.
It's a unidirectional profile, which just means we're bringing from one source, writing it out to a single target. And I’ve got task options set for Full Load and apply changes.
Okay.
So, now the next thing I need to do is to take a source endpoint. For me, I’m going to use my source SQL database and I’ll drop it in there; and then for my target, I’m going to use SQL as well, but this is a target SQL server.
So, those are different databases?
Oh yeah. There's many, many databases. I’ve got some set up for SQL, Aurora, Netezza, Snowflake, Kafka… We have I think there's 30 or so source and target endpoints. There's quite numerous.
Okay. But basically, this task is set up to copy data from one SQL server to another, but we're going to add a slight transformation and add a little extra data there?
Absolutely.
Okay, what's next?
So, the next thing you do after you get your endpoints; I’m going to do my table selection. And this is where I can look into my source. I’m going to go for this particular schema: DBO schema; and I’ll just do a wildcarded search. I’ve got a very small database that I work with, makes it a lot easier for running tests and easy to demo.
Okay.
The beginning, I’m just going to put in a Customer Table; and now I’m going to go out to the Global Rules. I’m going to add a rule, transformation.
I see you have lots of options there.
Oh yeah, plenty. Each one has specific things that you can do. I’m just going to do the rename of schema, and instead of taking it from DBO and putting it to DBO in my target; I want to change my schema in the target. So, I’m going to rename the schema to my initials “ML.”
Okay.
And then I’ll give it a meaningful name. So, I’ll finish this; and there's my first Global Transformation to rename the schema on the target side. We don't touch the source side in these transformations. And then the next thing I want to do is rename all of my tables. And this is kind of neat; I’m going to do it on any table coming from the source with any schema name, and I want to actually do this one which is to add a prefix.
Okay.
That'll be a string that gets added to the beginning of the table, and I’m going to add “TRN_”
And what does that stand for? Just transform?
Just transformation, for this demo purpose.
Okay.
And this is a rename table; and now I will Save this.
Okay.
Anytime you do a transformation, it'll detect it in the task and tell you: you need to Save your data. And typically, you need to rerun just tell it to start processing.
Okay.
So, this now starting the task. I’m doing the Full Load version. This process brings all of the base table Customer from the source and writes it to the target. We haven't done anything with changes yet. This is just the first phase of the task.
Okay.
At this point, I’m going to look at SQL server now, but first off, the source - just to show you the tables that I use. Here the Customer Table here.
Right there it is.
It's a very small table; just like I said, the smaller the easier it is to load and run. And then I might as well load the other table up; so, we can look at that. Orders is what I’ll be using.
Okay.
What I want to do now is show the target side, because this is source. We'll take a look here at the SQL server target; and there you go you can see that I ran that Full Load it's created these 2 tables, and you'll notice here that instead of DBO writing to ML (that was the first transformation to change the schema) and then the second transformation you'll see is I have TRN_Customer and TRN_Orders.
Right, because you did it for all tables. Okay.
Yes. At this point, you'll see I’ve copied everything over from the source to the target. These are essentially identical at this point.
Okay, and so, far all we've really done is changed the names of the tables. The data inside is still the same?
Correct. Want to now add another transformation at the global level.
Okay.
So, I’m going to stop my task. I know the task is going to want to stop when I add another transformation.
And normally, that task and Replicate just keeps running? What it will do is continually update the source database according to the rules you've set to keep that data up to date at all times, right?
Actually, yeah. It'll be reading from the source, but updating the target.
Okay.
And it does that in the change processing phase.
So, what transformation do you want to add next?
Ah, perfect. I’m going to go back into Designer. I’m going to add one more Global Transformation to have an update date column. So, that whenever a record gets updated in the source, you will see that date and time that it got updated; and this is not something you'll see in the source. I’m adding this to the target.
Okay.
It's an add column; and I want it to happen for any schema and any table that I have in my source; and I’m going to call this Update_Date.
Okay.
And now I’m going to create an expression for it. And this expression language I’m using it's based on SQLite. Our documentation is more specific to the functions that we have that Replicate needs to use, but the whole thing is based on SQLite; and if you need to look into the syntax of the SQLite, the best thing to do is Google search on “SQLite Syntax” and you can get all sorts of examples of how to write SQLite.
Okay.
So, I’ve cut and pasted this from another sheet I have. This is the expression. What I’m doing here is: I’m doing a case statement, because I only want this transformation to run when the operation Replicate senses from the source is an ‘Update.’ Because this is Update_Date, I don't want this to run on Insert, don't care if it runs on Delete; and that's one of the reasons why this will work for a global, because I have nothing table specific in here. I’m just looking at what operation is happening. And I’m going to say if it's an Update, put the datetime (‘now’) into that field that I just created called Update_Date.
Okay. Any time the data and the source changes and gets copied over to the target, you'll add the latest date when that happened?
Absolutely.
Okay.
So, I will be able to parse this expression, and I can put in the word ‘Update’ here; and when I test this expression, we'll see that it put out a date.
Okay.
If I were to parse it again, and put in the word ‘Insert’ and test it, you'll see I don't put anything and that's fine. I don't want anything to write out there. If it's an ‘Insert.’
Okay. So, it's looking for that term? All right.
Yeah. Yeah, and it's hit or miss what can actually be tested. This one I happen to know is testable. Change my data type to be a datetime.
Okay.
Change the column name to Update.
Okay.
So, now I’ve got three transformations and those are all at the global level. I will Save my task, and now I’m going to reload my target.
Now, because this is the first time you run with that update transformation, will it all say that Now is the Update_Date, since it's the first time it's been loaded or we'll wait for the data to change?
That is a great question, and it will wait, because remember when I did this transformation? I used a specific operation indicator that was ‘Update.’
Yeah. Yeah. So, that's at the global level. So, at this point let me show you in SQL server what it has done.
Okay.
We see what we have here is just a base table as it originally was copied; and you'll see we have an Update_Date field: and it is null, because we're only going to update when the record changes on the source. So, I might as well demo that right now. I’ll go into the source.
Okay.
And I will change Troy to Mike. I’ll go back out to Replicate, look at the Monitor screen, you'll see that we had a single update. It pushed through to the target. And now go back to SQL server, you'll see we have an Update_Date.
Right. That is great. Is there a way to add a field that will give a date for when the data was inserted into that table?
Yes. Yes, there is I’ll go back into the task and I’ll show you how to do a table level transformation. So, back in Designer mode I’m going to highlight, and then say Table Settings.
Okay.
Hit the transform, and now I’m going to do another Add Column; but this is just for this table. And I will change it to be a date; and I’m going to build my expression. And once again I’m just copying expression I already had built. So, with this case statement I’m saying: hey, if it's an ‘Insert,’ put in the datetime (‘now’). And a lot of customers will just do that. That works fine for the first Insert, and you get a date value, but later on (as most source databases have an update to that same record), if you don't have this second part in the ‘ELSE,’ the Target Lookup, that insert date will get wiped out, it'll become a null.
Ahh.
Now we're doing an Update, the ELSE is the Update; let's go out to the target, let's go out to that schema, to that table name and the target, use that Insert Date, and do a lookup, and I’ll pass it the customer key value; so, that it can go out to a Lookup and put that value back in. And this one is one of the examples of something you cannot test it.
Okay.
But you can parse it; and it looks like you can test it, but you really can't, unfortunately. But at least you can parse it, so you know you don't have something like a comma out of place or missing a parenthesis or something like that.
So, just - so, I understand, basically that ELSE expression you've got there takes a look at the target, sees that there already is an Insert, and it preserves it; so, it won't get wiped to a null?
Correct.
Okay.
All righty. I’ll say okay to that; and it'll ask me to Save the transformation.
It's nice to see that prompt there.
Yes. Yes, and then this prompt’s significant as well, because it always warns you that tables that have been transformed and modified, they'll only be applied after the affected tables are reloaded or resumed.
Okay. And right now the task is stopped, right? So, it's not really working?
Right. And I’m actually going to reload. So, I’ll Save the task. I’ll come back out and I will do a reload target; and once again we're in the Full Load section of this. It has completed one target, 5 records have been transferred. Go over to change processing; nothing happened yet. So, I’m going to go out and do an update. We can see now that we actually have –
Oh, I see we've got some insert dates.
Yes, because I reloaded them; Insert ran on every single record that was copied from the source to the target during the Full Load.
Okay.
Now what I want to do is: go out to the source Customer Table; and I’m going to do another update.
Okay.
Go back to Replicate. We can see that the update was applied to the target. When we go out in SQL server -
All right. So, it's got that update date.
Right. And we still have the original insert date that hasn't changed.
Okay.
And that's what that Target Lookup does for us. In this case, we preserve the insert date that is already existing in the record in the target.
I’m just always amazed at how smoothly Replicate works. Like it - just you set it, and everything just works, and keeps your data up to date. But that's great how you set up the transformations to really preserve those two new fields, and that can be really valuable too.
Oh yeah. Customers do this all the time. You know where it's really important to do an insert date like this: where the target database was Snowflake. No other way to tell Snowflake to do an insert date. So, we're adding functionality (if you will) to the Snowflake target, by letting the target know ‘hey, this is when this record was inserted, and this is when it was updated.’
Yeah; it's very cool.
Yeah, I agree.
Okay. Michael, how can customers take data from two tables, and join them together?
A very good question, Troy. In fact, we don't support a view for replication. Only under very specific circumstances, to get a record to have a field from a second table (a different table) on the source. We would use a Source Lookup transformation.
Okay.
And it's based at the table level. What I want to do before I even go there; stop my task. And what I’m going to do is add in the Orders Table.
Okay, yeah. So, we've been looking at the Customers table. We want to add some data from the Orders Table as well?
Yes. I want to include the Orders Table in my task. So, I need to go to Table Selection; and I’ll look up my source schemas, and table names I’ll highlight orders bring it over now I’ve got the two tables in here and I’m going to Save it, and I’m going to rerun it. So, we can take a look at that Orders Table in the target.
Okay.
This time, I’ll take a look at our Orders Table as a source; it's only got 5 fields. One of the fields in here is an Order Key; and the other field I have in here is called a Foreign Key. And this relates to the Customer Table; that's where I want to go look up. I want to bring in a field called Company Code from the Customer Table; and add it to the Order Table in the target.
Okay.
If we go look at our source, you'll see that there are cus keys here; but you'll notice the Orders Table does not have Company Code.
Okay.
Back to Replicate. And I have stopped my task.
Right, because basically anytime you change the rules with a task, they won't be applied until you Save and rerun?
That's correct. So, I’m going to go out to Designer. I’m going to select my Orders Table; hit table transformations. And once again, I’m going to add a column. I’m going to call it Company Code.
And this table already has the prefixes added to it from your previously applied global rule, right?
Yes, that's correct. Yes, you can see the ML is the schema name and the TRN_ prefix has already been applied.
Okay, that's great. So, from a high level, that's the difference between a Global Transformation and a Table Transformation?
That's correct. Yeah, Globals will happen to every table in your task.
Okay.
Back into Replicate; and I’ve added Company Code. I’m going to leave it as a String; and the expression I want to do here is another Source Lookup. So, this is going to go out to the source table called Customer. I’m in the “Orders Table” in the target, but I’m telling it I want you to go Look Up into the Customer Table and pull back the Company Code and stick it in the Orders Table in the target.
Okay.
So, essentially, I’ve done that join; but I’ve done it one field at a time. You notice, I don't have a case statement around this. I want this transformation to run every single time, whether it's an Update or an Insert. It needs to run and populate this Company Code field.
Okay.
I’ll say okay to here, and once again. We get a warning that we must Save it and apply that transformation by re-running. So, I’m just going to do a reload.
All right.
And we can see that we've completed the 2 tables: Customer and Orders. Both have loaded up; and now I’ll go out to SQL server. I now have not only the Update Date,
The Company Code.
That did the lookup for me and it populated the records in the target.
That's great.
Well, let me do an update of the Cust Key; change it to 3 which we hadn't seen before. We'll look at Replicate. We'll see the Orders caught a change.
Look at that.
So, that was me changing the Cust Key, and that's actually going to change the value. If I were to look at that there, we go that now, the Cust Key has changed to 3 from 4, and you'll see that we changed - so, we have a different Company Code.
Okay. Can you show us how to change the name of a specific table instead of doing the Global Transformation we did earlier?
Right.
Just to demonstrate, what I’ll do right here, I want to highlight Customer; I’m going to go to Table Settings in the General section. We've been going to Transform, but in the General section for the Customer Table, I can do a rename of that table to CST. Now, when I run this, something's going to break. I’ll give you a hint: when we wrote the transformation to look up the target, we use a very specific table name. That table name is about to change from Customer to CST. I can parse; it doesn't do much, just a syntax check. I’ll say OK, and I will Save; and I’m going to rerun this and I’ll reload my target. Full Load did complete fine; nothing's happened on change processing yet. So, let me go back into SQL server. You'll see that my Customer Table name changed to just CST. So, that overrode. Remember the table was called TRN_Customer (that was a Global Transformation for renaming a table), but I put a rename table right down on the table level itself which overrode the global.
Okay, but from my perspective, it didn't overwrite; because the old one is still there: TRN_Customer.
Oh yeah, yeah. I never told it to delete it. You'd have to manually delete this, yeah. So, you'd have to do that clean up manually.
Okay.
But if we were to look at Customer, I want to make another change.
Okay.
And we might as well check it out; and Replicate. We can look here that the Customer got a couple of updates, and we can see the changes happened.
Okay. Would you mind going back to Replicate? I noticed some error messages popping up there. If things don't go as expected, how can customers investigate further to help understand what's happening actually?
That's a good question. And you can see right here that this is one way to look at an error message and see what's going on. I’m going to do view logs.
Okay.
If you scroll down; it's kind of a small little editor and it takes a chunk at a time. But if you keep scrolling down, we should see the error messages right here. The same ones that were displayed.
Oh, it's nice that they pop up in red so it's easy to identify.
Yes, I do like that. Here's the error. It failed to prepare the statement, and it's trying to get that insert date right from the ML.TRN_CST. That was my mistake, because I changed the transformation on the Customer Table, but I left the TRN_; and you can see. I’m looking up into TRN_CST, and that table doesn't exist in the target.
Right.
So, I could remove the TRN_CST from here.
Okay.
I’ll parse for a syntax check, and you notice our last parsing didn't really catch that.
So, I guess that's what you meant by hit and miss. Sometimes it's working, sometimes it's not.
Yeah. It depends on the transformation; just does a syntax check on the actual SQLite you've written here.
Okay.
So, I’ll say okay to that. I’ll reload; and the Full Load completed both tables. No changes yet. So, I’m going to go out to SQL server.
Okay. So, we're back at the source side Customer Table.
And I’ll make a bunch of changes here.
Okay.
And now, when we look at the target side, you can see that those changes came through. And we now have the Update Dates.
Okay.
And just to show there's nothing up my sleeve, let me get back out to the Replicate task; and we do not see any error messages here anymore.
Now, all those expressions you're using, where can people find some examples of that? Where can they look for some more information around transformations?
Very good question. Best thing to do is hit the Help button right inside the Replicate console.
Okay.
And I’m going to search for Lookup; and it'll go through and find the functions; which is what we're using: a function. I can come down, and we have several different functions that we do document; and once again, most of this stuff is SQLite syntax. A Data Enrichment is what I’ve been using.
Okay.
And if we look at the Data Enrichments, here's documentation on the Source Lookup and
on the Target Lookup.
It's so convenient that there's a link to it straight from the product. Are there any articles we should be aware of as well?
Yes. There's a couple of articles out in the community. So, this talks about Target Lookup Insert Date. It is a field-level transformation. Gives a general form, like we just saw in the Help file.
I see it talks about all those parameters used in the expression.
Correct. Couple of caveats: these lookups could have performance implications. You need to test it, because if you put too many of these lookups; each one of them is an individual read from the source. You can start to increase your latency.
Okay, it's good to be aware of that.
Remember, we showed you the case statement. Is it an Insert operation, then we do the Insert. If it's an Update, then we want to do the lookup. So, this is the transformation code that we used. If it's an insert, put in the datetime (‘now’). If it's a not an Insert, the ELSE will trigger, and we do a Target Lookup.
That's great having an example people can start from and then change the details to apply to their specific tables.
Yeah. I think it's a valid way to learn it, definitely. And let me show the other transformation we used. There's – I want to call it a magic number: it's the RRN number in an Oracle table.
Okay.
And it can function as a primary key. You can't do a lookup with no primary key, it just will take too long. You can see it's very similar syntax; the same sort of thing: what's your duration? What's your schema / Table? What's the expression? What are your conditions?
Yeah, this is great. Now it's time for Q&A. Please submit your questions through the Q&A panel on the left side of your On24 console. Michael, how about if we read the first question? We just take them one at a time?
That sounds good to me, Troy.
All right. First question: is there a SaaS version of Replicate?
Yes, there is. I don't want to speak for product management, but I have heard there is a SaaS version being prepared; and the best way to get information about that would be to check with your Sales Rep, and they can check with product management directly to give you the latest news.
All right, next question: is it possible to include SQL statements more complex to extract data from a database?
No, not really. Unfortunately Replicate has to deal with a single table at a time as its source, but in order to adjunct the missing functionality, we do have the Source Lookup (which I did demo in this presentation).
Right.
So, that allows you to get a couple of fields from a separate table and bring them into a table in the target. So, it's kind of like doing a Join, but we do it with a Source Lookup.
Okay, great. next question: how do Qlik sense and Qlik Replicate work with each other?
Basically, Replicate prepares and moves the data over to a location that Sense can work with it.
Right; next question: is adding a new column to every table with load time of the table?
Yes. We can do that. Actually, that's something else that was in the demo. What we did in our transformation was: we put in an Insert Date, and we populated that with a datetime value. So, that you would know in that record it may not be existing in the source, but in the target. We added a field insert date and we populate it as the Insert happens. We also populate it (in our demo) an update time.
Great. It's nice to see that demonstrated for people. So, we can go back, and by the way this recording will be available. And if we don't get to answer all questions today, we will submit questions and answers along with the recording on Qlik community. All right, next question: is there a way to obfuscate some sensitive information in a target table like social security number or email addresses? What would you recommend?
Yes. We definitely can obfuscate. We do that by adding a transformation to the field. And it could be as simple as just replacing the social security value with something like 123-456-789.
Okay. So, that would be something you do in the expression editor?
Yeah, exactly. And then a lot of customers, they actually get pretty involved in this; and they can call with our lookups, they can call subroutines and other things they've written to (you know) do more complicated obfuscation, but for sure we can do it.
That's great. I could see a lot of use cases for that, especially with QDPR. All right. Where are the log files stored? I remember we saw a little demo of them pulled up in the Replicate console, but where are they actually stored?
Oh, sure. I can show you that. They're basically under the Replicate folder. Under the data folder, and in the logs directory.
Okay.
And I have that right here. Where you can see, I’m on Windows Program Files > Attunity > Replicate > Data, and Logs. And in here are all the various repcmd logs; got task logs in here; everything basically lands in here. You can see some of my task logs, and other logs like our repuictl. So, basically all of your logs are stored in this logs directory.
Okay, and when you're doing troubleshooting, which logs usually look at?
A good question. Number one logs we would like to have are our actual task logs. The task logs are going to contain the information about the specific task you may be having an issue with; but also, the good logs to have are the rep command log.
Okay.
And a good thing about our task logs is: we do have a very good time-date stamps and error messages. So, you'll be able to see the exact time and date something happened and then you know what log to grab.
Okay, moving on to the next question: can you transform data from different sources like MSSQL or and Oracle into a single target?
Yes, absolutely. You can do that, you need to use two different tasks; because one of the limitations of Replicate is having a single source database. For instance, MSSQL. So, if you needed to get into the target a different source database like Oracle, you would just have to create another task. The two of them can point to the same target. there are some caveats there; if they're going into the same table on the same target you want to make sure you don't have any violations of primary keys or that sort of thing, but you certainly can take multiple sources and put them into a single target. One of my favorite examples of that actually (it's really cool) is: in an environment where there are multiple databases all the same but they're different plant codes, and you want to consolidate them. Because maybe they're separated geographically around the country. And that's a great feature we have is to be able to write into the single target from multiple different sources.
That's very cool. Next question is: how can you see if a task has encountered an error? Is there a way to trigger an email or notification to the administrator?
Absolutely. There's a section. I’ll show you that one. When you're looking at the Qlik Replicate console, there's a tasks button up on the left side. If you down arrow, you get into the server side. Notifications are in the server side of a task. It's basically for every task; and you have the ability to put in notifications right here, you can put in new notification like task events or server events. But as you say, an event that you really want to track is errors. So, we have that right down here. You expand this, and we have the ability to send a notification out if a task is stopped; if there's any error any warning; or if table processing was suspended due to errors. The other good one that people use for notifications is latency. Because one of the things you want to have is your data current on that target, and if you all of a sudden have something going on and your latency is normally (let's say) 4 or 5 minutes, and all of a sudden it's up to 15 minutes; you might want to get a notification sent out on that latency. That is increased from what you expect and what you believe to be normal.
That’s really powerful. That's great that you have so much granularity with how you can set the notifications.
Oh yeah, yep; and you can actually set them at certain number of seconds. You can clear them if it drops; you can set it for a memory usage or disk utilization.
Wow, that's great. I wasn't aware of that. Is there an expression or modifier to convert the time from UTC to my local time?
Yes, basically that's a SQLite date function, and one that you would use is called a Date Add.
Okay.
And you can either put (let's say) 5 hours on to the date that's in the field, or you can subtract a few hours; whatever the amount of hours you're off from UTC time, you can modify it.
Okay, next question: I notice under the transformation scope, there's a “Column Name is Like,” can I use this to create a transformation rule that will combine first name and last name?
Yeah, I’m not really sure you'd even want to; and I don't think that would work at that level, but what you can do (and it's very easy) is: at the table level if you're trying to concatenate two fields; you would do that by doing a transformation. And you would have (let's say) the field name is called Full Name; and in the expression builder, you would reference the First Name and an ‘&’ maybe a space, and then the Last Name, then you would have a new field in the target which you have named Full Name, and it would have both first and last name.
That's a great solution. Okay, we have time for one last question: will a Full Load be necessary after changing or editing a transformation?
Not all the time; it really depends on the transformation you're doing. For instance, if you were doing a transformation like we did where I did a Source Lookup to add a field from a different table into the target table, I think ours was order header fetching from customer, getting the Company Code. So, in that case, if you don't reload that table, all the existing records are not going to have that field value in it. So, in that case yeah, you probably want to do a Full Load. But there are times when you certainly don't want to do a Full Load. And there are a couple of ways to do that which you do need to test for your specific environment and use case. And a resume will conditionally load or not load once again depending on the type of transformation. But if you are set on not having it trigger a full load ever, then using a restart with timestamp; all that will do is refresh the metadata. It'll put the transformation in place, and it will not run any Full Load ever.
Okay. It's nice that there's a lot of options there. All right, well thank you very much, Michael. I think this can be helpful for a lot of people.
Well, thank you very much. I really appreciated the opportunity to do this webinar with you. And certainly if you have any questions or are working on transformations, or for that matter anything; but do open a ticket. Open it early, because you'd be surprised what the support group has seen. And where you might be looking at why isn't it working for a day or two, you open that case early before you get frustrated and let us look at it, because we've got a lot of answers that we can send out pretty quickly.
Thank you everyone. We hope you enjoyed this session. Thank you to Michael for presenting. We appreciate getting experts like Michael to share with us. Here is our legal disclaimer. Thank you once again. Have a great rest of your day.

 

Contributors
Version history
Last update:
‎2022-06-27 08:10 AM
Updated by: