I started a new job a few months ago and am noticing some of the older SSIS packages are built with dummy tasks. For example, if there is a Execute SQL Task and it produces a Boolean result, the True result may go to the task that needs something done. However, there is also a dummy task for False that does nothing and is labeled as such.
Here's an example of what I'm seeing.
Is this a best practice or proper way to code these types of Tasks? The way I code these types of tasks is to only code the needed task and ignore the other. In the case of my image example, I would code the True but not add a task for the False.
Just curious if I'm doing something wrong here.
Why adding a dummy task that does nothing?
(1) Informing Developers
If the goal is Informing developers that edits the package then you can write an annotation beside of the True precedence constraint, and write that if False result is not considered or does or does nothing
(2) For Debugging purposes
If the adding a dummy task is for debugging purposes, then it is not a bad idea. Because it will make the package flow more clear for the viewer. But you have to disable this component before deploying the package on the production server.
(3) To apply an expression
If the goal is to apply an expression in the precedence constraint like mentioned in the comments, then the proper way is to use an Expression Task (in case that it is connected to a dummy task)
Also based on this Microsoft article:
A precedence constraint can use an expression to define the constraint between two executables
So if expression are needed, then write it in the True precedence constraint, or if expression is needed to assign some values to a variable then like i mentioned above use an Expression Task
In one line standard practise is to create the log if something does not go according to desired logic. It should be logged for future debugging.
If you are expecting true as a result of some boolean logic and it turns out to be false then there should be some structure to log it.
Now coming to use of dummy task it is of no harm but instead of that, some task should be used which can create some logs for future reference.
Related
Firstly, I am new to SSIS and not sure of what format to explain the problem in a repeatable way for testing
So I have a task that loops through a folder looking for flat files and if in the correct format loads them into a SQL server staging table. This seem to work correctly
The next bit is the strange bit. I have a split for success and a split for failure (for user notification etc) on both legs I run a SQL task to count the number of rows in the staging table to process. IF it greater than zero I want to run my SQL stored procedure that handles the load to into the main database table for the data, then clean up.
In my debug email I see the number of rows is greater than 0 but the task does not proceed. I can not understand why. I have tried a number of constrain combinations (On completion, On Success, On Success and RowsToProcess>0).
I have also tried removing and adding my SQL Task and remapping.
(BTW all my tasks function in SSMS etc)
Nothing seems to work The only thing is that 2 branches re-join at this point, but surely that would not affect it, would it? (see below original screen shots)
Here is my control flow, If I have missed anything please add a comment and I will supply the information if I know it
My results from executions
On further testing two executables does seem to be the problem! So, additional questions.
Is this expected behaviour that two constraints joining back to a SQL task stops the flow in SSIS (in BPA task centre it does not)?
If, this is the case does this mean you have to repeat code in parallel? (for example if I was to run a clean up script at the end of my flow I would have to write it tice once for success leg and once for failure leg). This seems inefficient, am I missing something?
I think I've found the answer you are looking for here (go give it an upvote)
I was not aware of it, but basically, it says that bot branches must complete successfully (logical AND) in order for the flow to proceed, which won' happen as the right branch in this case won't even run.
The default behavior can be changed in the "constraint properties" (right-click on the arrow that links the blocks) under the "Multiple Constraints" section.
That said
I've never used this method, but that's up to the use case. I would have used "sequence containers" to avoid replicating blocks or multiple constraints, which is not the same but works as long as you don't have to pass data from one block to the other.
In your case, I'd put all the blocks inside a sequence container except the last 2, and after the container completes execute the last two as they must be always run after the previous block of operations
note about containers:
Containers do not output data but are useful to group operations logically, and you can even run just a container instead of the whole package (from VS).
Seems today I've learned something new too...
Hope this helps you solve your issue
Error:Apex trigger AccountAddressTrigger caused an unexpected exception, contact your administrator: AccountAddressTrigger: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.AccountAddressTrigger: line 6, column 1
while solving Create an Apex trigger for Account that matches Shipping Address Postal Code with Billing Address Postal Code based on a custom field.
I got the above mentioned error
I had write correct logic but still get the error.
Your question is really poor, post the code you've writte so far and/or link to that challenge (what is it, a Trailhead task? Homework? Job interview?)
My guess is that your trigger should operate as "before insert, before update", not "after". Before's are for all kinds of validations and field prepopulation and one of notable features is that you don't need to explicitly write update myrecords; - you get save to database for free. After's are more for side effects like creating related records, anything that makes sense only after you generated record's Id.
I have a question on how to set up precedence constraints in SSIS.
I have the following flow in the package:
The execute SQL task returns a string value in this format '1111' that is then stored in the variable called "data"
The point of it all is to control which script tasks gets to execute
For example, if the value is "1111" then all 4 scripts get to run.
If the value is "1011" then scripts 1,3,4 get to run... you get the picture
The scripts DEPEND on the previous one in all cases.
The constraints evaluate with an expression such as this: SUBSTRING(#[User::data], 2,1)=="1" for script 2, for example.
The problem:
If one of the scripts dont run, then the next one wont either (because the constraint never got to the evaluated). For example, for data = "1011", the scripts 3 and 4 never get to run because number 2 never ran...
Do you know a better way to make this work?
Using SQL Server 2008 with BIDS
I agree with #Iamdave for his direction that says modify your script in each script do the check there if it should or should not execute rather than using expression constraints.
However, because someone might want to do this with Data Flow Tasks or something here is a way to do it with SSIS components. Your problem is that you want to conditionally execute a task but whether or not that task gets executed you then want to conditionally execute another task. By placing each script task in a Sequence Container the precedence between sequence containers will always make the other container execute as long as that prior container does not fail or does not have a expression as a constraint. But once in the container you need to be able to set a Conditional Precedence. You can do that by adding a dummy task of some kind ahead of the script task and adding the constraint on that precedence.
Add some conditional code into your scripts.
For example, at the start of script task 1:
if firstcharacter(Variable) = 1
do things
else
do nothing
And then in script task 2:
if secondcharacter(Variable) = 1
do things
else
do nothing
and just make sure that all the data passes through, only being transformed if the right character in your variable is met.
Is it possible to capture the query text of the entire RPC SELECT statement from within the view which it calls? I am developing an enterprise database in SQL Server 2014 which must support a commercial application that submits a complex SELECT statement in which the outer WHERE clause is critical. This statement also includes subqueries against the same object (in my case, a view) which do NOT include that condition. This creates a huge problem because the calling application is joining those subqueries to the filtered result on another field and thus producing ID duplication that throws errors elsewhere.
The calling application assumes it is querying a table (not a view) and it can only be configured to use a simple WHERE clause. My task is to implement a more sophisticated security model behind this rather naive application. I can't re-write the offending query but I had hoped to retrieve the missing information from the cached query plan. Here's a super-simplified psuedo-view of my proposed solution:
CREATE VIEW schema.important_data AS
WITH a AS (SELECT special_function() AS condition),
b AS (SELECT c.criteria
FROM a, lookup_table AS c
WHERE a.condition IS NULL OR c.criteria = a.condition)
SELECT d.field_1, d.field_2, d.filter_field
FROM b, underlying_table AS d
WHERE d.filter_field = b.criteria;
My "special function" reads the query plan for the RPC, extracts the WHERE condition and preemptively filters the view so it always returns only what it should. Unfortunately, query plans don't seem to be cached until after they are executed. If the RPC is made several times, my solution works perfectly -- but only on the second and subsequent calls.
I am currently using dm_exec_cached_plans, dm_exec_query_stats and dm_exec_sql_text to obtain the full text of the RPC by searching on spid, plan creation time and specific words. It would be so much better if I could somehow get the currently executing plan. I believe dm_exec_requests does that but it only returns the current statement -- which is just the definition of my function.
Extended Events look promising but unfamiliar and there is a lot to digest. I haven't found any guidance, either, on whether they are appropriate for this particular challenge, whether a notification can be obtained in real time or how to ensure that the Event Session is always running. I am pursuing this investigation now and would appreciate any suggestions or advice. Is there anything else I can do?
This turns out to be an untenable idea and I have devised a less elegant work-around by restructuring the view itself. There is a performance penalty but the downstream error is avoided. My fundamental problem is the way the client application generates its SQL statements and there is nothing I do about that -- so, users will just have to accept whatever limitations may result.
I know some ways that we can use in order to determine that whether our own Stored procedure has been executed successfully or not. (using output parameter, putting a select such as select 1 at the end of the stored procedure if it has been executed without any error, ...)
so which one is better and why?
Using RAISERROR in case of error in the procedure integrates better with most clients than using fake out parameters. They simply call the procedure and the RAISERROR translates into an exception in the client application, and exceptions are hard to avoid by the application code, they have to be caught and dealt with.
Having a print statement that clearly states whether the SP has been created or not would be more readable.
e.g.
CREATE PROCEDURE CustOrdersDetail #OrderID int
AS
...
...
...
GO
IF OBJECT_ID('dbo.CustOrdersDetail') IS NOT NULL
PRINT '<<< CREATED PROCEDURE dbo.CustOrdersDetail >>>'
ELSE
PRINT '<<< FAILED CREATING PROCEDURE dbo.CustOrdersDetail >>>'
GO
SP is very much like a method/subroutine/procedure & they all have a task to complete. The task could be as simple as computing & returning a result or could be just a simple manipulation to a record in a table. Depending on the task, you could either return a out value indicating the result of the task whether it was a success, failure or the actual results.
If you need common T-SQL solution for your entire project/database, you can use the output parameter for all procedures. But RAISEERROR is the way to handle errors in your client code, not T-SQL.
Why don't use different return values which then can be handled in code?
Introducing an extra output paramter or an extra select is unnecessary.
If the only thing you need to know is whether there is a problem, a successful execution is good enough choice. Have a look at the discussions of XACT_ABORT and TRY...CATCH here and here.
If you want to know specific error, return code is the right way to pass this information to the caller.
In the majority of production scenarios I tend to deploy a custom error reporting component within the database tier, as part of the solution. Nothing fancy, just a handful of log tables and a few of stored procedures that manage the error logging process.
All stored procedure code that is executed on a production server is then encapsulated using the TRY-CATCH-BLOCK feature available within SQL Server 2005 and above.
This means that in the unlikely event that a given stored procedures were to fail, the details of the error that occurred and the stored procedure that generated it are recorded to a log table. A simple stored procedure call is made from within the CATCH BLOCK in order to record the relevant details.
The foundations for this implementation are actually explained in books online here
Should you wish, you can easily extend this implementation further, for example by incorporating email notification to a DBA or even an SMS alert could be sent dependent on the severity of the error.
An implementation of this sort ensures that if your stored procedure did not report failure then it was of course successful.
Once you have a simple and robust framework in place, it is then straightforward to duplicate and rollout your base implementation to other production servers/application platforms.
Nothing special here, just simple error logging and reporting that works.
If on the other hand you also need to record the successful execution of stored procedures then again, a similar solution can be devised that incorporates log table/s.
I think this question is screaming out for a blog post……..