October 6, 2010 at 1:48 pm
Hey folks,
I'm trying to construct a procedure which will duplicate a block of users in one organization to another organization without having to resort to using cursors.CREATE TABLE [Test_Users](
[User_id] [int] IDENTITY(1,1) NOT NULL,
[org_id] [int] NOT NULL,
[first] [varchar](10) NULL,
[last] [varchar](10) NULL,
[local_id] [varchar](20) NULL
) ON [PRIMARY]
SET IDENTITY_INSERT [Test_Users] ON
INSERT INTO Test_Users ( User_id, org_id, first, last, local_id )
SELECT 1, 10, 'John', 'Doe', 'JDOE' UNION ALL
SELECT 2, 10, 'Jim', 'Jones', 'JJONES' UNION ALL
SELECT 3, 10, 'Bob', 'Barker', 'BBARKER' UNION ALL
SELECT 4, 10, 'Richard', 'Nixon', 'RNIXON' UNION ALL
SELECT 5, 50, 'NewJim', 'Jones', 'JJONES' UNION ALL
SELECT 7, 50, 'NewBob', 'Barker', 'NEWBEE' UNION ALL
SELECT 6, 50, 'NewBob', 'Barker', 'BBARKER'
SET IDENTITY_INSERT [Test_Users] OFF
SELECT * FROM Test_Users
So here's the scenario: We upload a block of users into the table under Org_ID = 50. I need to then basically duplicate all of the users in Org_ID = 10. The only thing I can be certain of here, is that I can JOIN Orgs 10 and 50 on the Local_ID field.
If I select all records from Org_Id = 50, I have my basic list of changes that need to be applied to Org_ID = 10. I will need to remove any records from Org_id = 10 if they aren't also in Org_id = 50. Seems reasonably easy since I only need a User_ID value to effect a delete. I can get that by doing this: SELECT *
INTO #tmpDELETE
FROM (SELECT user_id
FROM Test_Users AS u
WHERE u.Org_ID = 10
AND u.User_ID NOT IN (SELECT User_ID
FROM Test_Users
WHERE Org_ID = 50 ))
I think I can probably figure out something similar for the INSERT operation because the will be records for Org_ID = 50 that aren't in Org_id = 10's set.
The problem I'm struglling with here, is how to perform the updates (where there is a match on Local_ID between the two orgs.
I want to avoid inserting these folks as new records each time. I want to ensure that I update all of the columns except for the User_ID and the Org_ID. (The Local_ID value shouldn't matter since it should be the same...) I think I could do it with cursors, but I keep reading that cursors are a thing to avoid if at all possible. So is this possible to do without a cursor?
I think the resulting table should look like this:User_idorg_idfirstlastlocal_id
210NewJimJonesJJONES
310NewBobBarkerBBARKER
550NewJimJonesJJONES
750NewBobBarkerNEWBEE
650NewBobBarkerBBARKER
810NewBobBarkerNEWBEE
October 6, 2010 at 2:11 pm
I believe you're looking for this:
UPDATE tu1
SET
first = tu2.first,
last = tu2.last,
local_ID = tu2.local_id
FROM
#Test_Users AS tu1
JOIN
(SELECT
*
FROM
#Test_Users
WHERE
org_id = 50
) AS tu2
ONtu1.local_id = tu2.local_id
where
tu1.org_id = 50
Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.
For better assistance in answering your questions[/url] | Forum Netiquette
For index/tuning help, follow these directions.[/url] |Tally Tables[/url]
Twitter: @AnyWayDBA
October 6, 2010 at 3:34 pm
Many thanks Craig!
Your example was pretty damn close...with just a couple of minor tweaks I got it to work!
Here's the slightly corrected edition with the right table names:
UPDATE tu1
SET
first = tu2.first,
last = tu2.last,
local_ID = tu2.local_id
FROM Test_Users AS tu1
JOIN
(SELECT *
FROM Test_Users
WHERE org_id = 50
) AS tu2
ON tu1.local_id = tu2.local_id
where
tu1.org_id = 10
October 6, 2010 at 3:36 pm
Larry Kruse (10/6/2010)
Many thanks Craig!Your example was pretty damn close...with just a couple of minor tweaks I got it to work!
....
tu1.org_id = 10[/code]
Yawhoops... I'm the man of a thousand typos today. And thank you for posting a proper test harness that made it easy to work with. 🙂
Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.
For better assistance in answering your questions[/url] | Forum Netiquette
For index/tuning help, follow these directions.[/url] |Tally Tables[/url]
Twitter: @AnyWayDBA
October 6, 2010 at 3:38 pm
October 6, 2010 at 4:06 pm
Thanks Richard.
I'm looking at the BOL entry for MERGE (T-SQL) and it seems to indicate that it's used to merge two tables. Would it be able to work in the example I set forth above? The stuff in my example all resides in a single table. I actually simplified my example quite a bit because my actual user information resides in a pair of tables which I join using a view (for queries) or manually join on if I'm doing any kind of update/delete operation.
It could be most handy however if it can work from the same table. I will have to study the BOL description to see if I can figure it out and apply it in my case, because I will have INSERT/DELETE/UPDATE operations to perform with every reload of the initial organization's data.
Many thanks...I hadn't seen the MERGE command before.
October 6, 2010 at 6:21 pm
Merge command is handy because it's basically used as an 'upsert', an insert/update.
First, you'd do your deletes separate.
The MERGE would then insert and update simultaneously according to your key. If the key existed, it would update, if not, it would insert.
Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.
For better assistance in answering your questions[/url] | Forum Netiquette
For index/tuning help, follow these directions.[/url] |Tally Tables[/url]
Twitter: @AnyWayDBA
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply