Updating or Inserting records into table using informatica - insert-update

I have two tables ACC and ACC_Restrict. I want to check the values of the column, P_R of either tables to see whether I should either insert, update or do nothing to ACC_Restrict. If the value is active in ACC but not in ACC_Restrict then insert into ACC_Restrict if it is still active in both ACC and ACC_Restrict then do nothing. If it is not active anymore in ACC but is still in ACC_Restrict then update ACC_Restrict by updating end_date to today's date. How can I achieve this in informatica?
Edit: There has been a modification of the requirement. ACC will only contain modifications to the account of someone. So if nothing has changed in someone's account we don't see anything in ACC but that doesn't mean if he had a restriction before, it has been lifted. It's just because nothing has changed so it doesn't appear in ACC. How do I manage this?
Note: P_R is a restriction on an account. I put the end_date to a date close to infinity and when the restriction is removed from the account I update
ACC_Restrict by changing end_date to present date.

Related

Unable to implement SCD2

I was just working on SCD Type 2 and was unable to fully implement it in a way that some scenarios were not getting full filled. I had done it in IICS. Really finding it very very difficult to cover all possible scenarios. So, below is the flow:
Src
---> Lkp ( on src.id = tgt.id)
---> expression ( flag= iif (isnull (tgt.surrogatekey) then Insert, iif(isnotnull(tgt.surrogatekey) and md5(other_non_key_cole)<>tgt.md5)then Update)
----> insert on flag insert(works fine)
but on update i pass updates
to 2 target instances
of same target table
in one i am updating it
as new update as insert
and in other i
am updating tgt_end_date=lkp_start_date for previously stored ids and active_ind becomes 'N'.
But what happens is this works but not in when i receive new updates with again same records meaning duplicates or simply rerunning the mapping inserts duplicates in the target table and changing of end_date also becomes unstable when i insert multiple changes of the same record it sets all active_flags to 'Y' what expected is all should be 'N' except the last latest in evry run. Could anyone please help with this even in SQL if you can interpret.
If I’ve understood your question correctly, in each run you have multiple records in your source that are matching a single record in your target.
If this is the case then you need to process your data so that you have a single source record per target record before you put the data through the SCD2 process

SQL - Need to find a way to check whether a member has renewed

So, this is probably simple. I need to find a way to check whether a member of a scheme has renewed their membership or let it expire, I need to generate a simple list of those whom have not renewed.... There are complicating factors however, in that I cant use Excel, and it can only be a single step to Crystal reports (though I have solved the issue in Excel using a simple Countifs and if Formula)
Now for the problem.
The membership has specified Start/End Dates in separate columns in the table. It is easy to see whether this, in a row basis has expired. The issue is that if they have renewed, this is logged as a separate table entry linked by a Individual reference to the member. There are also multiple Qualifications I also need to test against.
So, whilst I can test the expiration date, the question is how can I test against the rest of the data, based on whether the Individual Reference and Qualification name and then check whether this is "Current". Doing this would enable me to therefore test whether the Membership has therefore been renewed, or not, on an individual line.
Any advice on methods would be appreciated.
Without knowing what data you have and making assumptions out the wazoo, try something along these lines
select distinct Member_id,
case
when exists (select 1
from members m2
where m2.member_id = m1.member_id
and (m2.expiry_date is null
or m2.expiry_date > '2018-01-25'))
then 'Active'
else 'Expired'
end as mem_status
from members m1
What the exists does is look and see if that member has an active status

Performance difference between max and greater than in SQL

While designing a table which have impact based on date (e.g. Currency Rate) which one is better?
Effective date (Find out max(Effective date) and get the current value)
From Date - To Date condition (With greater than equals sysdate)
Rgrds.
It depends. You have a table representing changes to a particular entity, and you want to record when the entity changed, and when the change was replaced by a subsequent change.
1. If you record just the Effective Date for each event, INSERTs are simpler: they don't need to find the earlier record to update it. However, querying becomes more complex - you'll need to run a window over the dataset to find which record is applicable at any one time, potentially resulting in poorer performance.
Another downside is that this model is open-ended; you can't record a currency as "permanently closed" (which you could do if you had an End date).
2. If you record the Start and End dates for each event, queries are simpler: you only need to look at each row individually to know whether it is "current" as of any point in time or not. INSERTs, however, are slightly more complex - when you insert a new event, you have to update the earlier event to mark its End date.
This model is closed-ended; you can put a End date on the final event and have no "open" record.

T-SQL Concurrency Issue : Auction / Bidding System

I am currently developing an online Auction system using ASP.NET 3.5 and SQLServer 2008. I have reached the point in development where I need to ensure that my system sensibly handles the concurrency issue which may arise when:
Two people - Geraldine and John - want to bid on the same auction item which is currently going for £50. Geraldine enters a bid of £55 and John enters a bid of £52. The system now has two copies of the page 'submit_bid.aspx' running; each copy of the page checks to see that their bid is high enough, they both see that it is, and they submit the bids. If John's bid goes through first then the auction item price is currently £55 and a moment later it's being replaced by a bid of £52.
What I need to do is to lock the auction item row until the current bid price is updated before allowing any other bidder to check the current bid price and placing a new bid.
My question is: what is the best practice way for doing this using T-SQL and / or ADO.NET?
I currently have an AuctionItem table which has the following fields (plus other fields I haven't included for brevity):
AuctionItemID INT
CurrentBidPrice MONEY
CurrentBidderID INT
I have performed some research and come up with the following T-SQL (pseudocode-ish):
#Bid MONEY
#AuctionItemID INT
BEGIN TRANSACTION
SELECT #CurrentBidPrice = CurrentBidPrice
FROM AuctionItem
WITH (HOLDLOCK, ROWLOCK)
WHERE AuctionItemID = #AuctionItemID
/* Do checking for end of Auction, etc. */
if (#Bid > #CurrentBidPrice)
BEGIN
UPDATE AuctionItem
SET CurrentBidPrice = #Bid
WHERE AuctionItemID = #AuctionItemID
END
COMMIT TRANSACTION
I have also read that if I include the SET LOCK_TIMEOUT I can also reduce the number of failed concurrent updates. For example:
SET LOCK_TIMEOUT 1000
...will make a concurrent update wait for 1000 milliseconds for a lock to be released. Is this best practice?
Source: "chrisrlong", http://www.dbasupport.com/forums/archive/index.php/t-7282.html
Here are the methodologies used to handle multi-user concurrency issues:
Do Nothing (Undesirable)
User 1 reads a record
User 2 reads the same record
User 1 updates that record
User 2 updates the same record
User 2 has now over-written the changes that User 1 made. They are completely gone, as if they never happened. This is called a 'lost update'.
Pessimistic locking (Lock the record when it is read.)
User 1 reads a record and locks it by putting an exclusive lock on the record (FOR UPDATE clause)
User 2 attempts to read and lock the same record, but must now wait behind User 1
User 1 updates the record (and, of course, commits)
User 2 can now read the record with the changes that User 1 made
User 2 updates the record complete with the changes from User 1
The lost update problem is solved. The problem with this approach is concurrency. User 1 is locking a record that they might not ever update. User 2 cannot even read the record because they want an exclusive lock when reading as well. This approach requires far too much exclusive locking, and the locks live far too long (often across user control - an absolute no-no). This approach is almost never implemented.
Use Optimistic Locking.
Optimistic locking does not use exclusive locks when reading. Instead, a check is made during the update to make sure that the record has not been changed since it was read. Generally this is done by adding a version/etc column (INT/numeric, holding a numeric value that is increased when an UPDATE statement is made). IE:
UPDATE YOUR_TABLE
SET bid = 52
WHERE id = 10
AND version = 6
An alternate option is to use a timestamp, rather than a numeric column. This column is used for no other purpose than implementing optimistic concurrency. It can be a number or a date. The idea is that it is given a value when the row is inserted. Whenever the record is read, the timestamp column is read as well. When an update is performed, the timestamp column is checked. If it has the same value at UPDATE time as it did when it was read, then all is well, the UPDATE is performed and the timestamp is changed!. If the timestamp value is different at UPDATE time, then an error is returned to the user - they must re-read the record, re-make their changes, and try to update the record again.
User 1 reads the record, including the timestamp of 21
User 2 reads the record, including the timestamp of 21
User 1 attempts to update the record. The timestamp in had (21) matches the timestamp in the database(21), so the update is performed and the timestamp is update (22).
User 2 attempts to update the record. The timestamp in hand(21) does not match the timestamp in the database(22), so an error is returned. User 2 must now re-read the record, including the new timestamp(22) and User 1's changes, re-apply their changes and re-attempt the update.
Comparison
Optimistic locking is database independent -- no need for mucking with isolation levels and database specific syntax for isolation levels.
I'd use a numeric column over a timestamp -- less data & hassle to manage
You don't need a transaction if just use 1 statement like this:
-- check if auction is over (you could also include this in the sql)
UPDATE AuctionItem
SET CurrentBidPrice = #Bid
WHERE AuctionItemID = #AuctionItemID
AND CurrentBidPrice < #Bid
IF ##ROWCOUNT=1
BEGIN
--code for accepted bit
SELECT 'NEW BIT ACCEPTED'
END ELSE
BEGIN
--code for unaccepted bit
SELECT 'NEW BIT NOT ACCEPTED'
END
I followed Alex K's suggestion above and implemented a 'Bid History'. Works a treat. Thanks Alex K.

I Need Help Fixing My Small Time Sheet Table - Relational DB - SQL Server

I have a TimeSheet table as:
CREATE TABLE TimeSheet
(
timeSheetID
employeeID
setDate
timeIn
outToLunch
returnFromLunch
timeOut
);
Employee will set his/her time sheet daily, i want to ensure that he/she doesn't cheat. What should i do?
Should i create a column that gets date/time of the system when insertion/update happens to the table and then compare the created date/time with the time employee's specified - If so in this case i will have to create date/time column for timeIn, outToLunch, returnFromLunch and timeOut. I don't know, what do you suggest?
Note: i'm concerned about tracking these 4 columns timeIn, outToLunch, returnFromLunch and timeOut
The single table design only allows an employee one break (I'm guessing that lunch is not paid). And it would be difficult to detect fraud short of auditing every record change. I'm thinking something like a two table approach would be more flexible and more secure.
Start by creating a TimeSheetDetail record for every event. i.e. Shift Start, Break Start, Break Stop, Shift End. Allow the employee to record whatever date and time in the Entered column. There may be legitimate cases where an employee forget to clock in or out.
It would be very easy to detect fraud by comparing the Entered value to the AddedOn value before Payroll or any other time an audit is needed. You could even detect small fraud where an employee constantly rounds up or down in their favor every day. Ten minutes every day over the course of a year adds up to extra week.
This design can be furthered secured by not allowing record updates or deletes.
CREATE TABLE TimeSheet
(
TimeSheetId
EmployeeId
AddedOn //populate using GETDATE()
AddedBy //populate using SUSER_SNAME()
);
CREATE TABLE TimeSheetDetail
(
TimeSheetDetailId
TimeSheetId
Type //Shift Start, Shift End, Break Start, Break End
Entered
AddedOn //populate using GETDATE()
AddedBy //populate using SUSER_SNAME()
);
If you're that concerned about employee dishonesty about their working hours, then install a manual punch card clock in/clock out system and treat them like factory shop floor workers.
Failing that, a trigger that archives off the changed record with a date-time stamp against it will allow you to see at what time every change to a timesheet was made, and a case for fraud could be made. So you'd need something like a TimeSheetHistory table, with the additional columns for time of change and user making the change (populated using GETDATE() or similar, and SUSER_SNAME() or similar if you're using Windows authentication).
Of course you are concerned about this, that is one of the basic requirements for most time sheet applications! No one should be able to change their own time sheet once submitted without a supervisor override. This is to prevent time-card fraud and thus is a legal issue and should not be subverted. Employees who get apid overtime could submit a correct timesheet for approval by the supervisor, then change it to add hours just before payroll is run and then change it back otherwise. This is critical feature that any timesheet application must have.
First, you need to have a history table to store a record of all the changes and who made them.
Next you need an update trigger that prevents updates unless a timesheet has been reopened.
Third you need a field for timesheet status. A insert/update trigger will ensure that only people in the management group can change a submitted status to a reutrned status and that no one can return his own timesheet to without a differentperson approving it. In the terms I learned when working for an audit agency, this is an internal control becasue it is known that it is far less likely that two people will join together to commit fraud than one person.