SQL Server 2008 Trigger to Update/Insert/Delete From Multiple Tables - sql

I have a table UserInfoComputed whose data comes from UserInfo and UserInfoComputed also have foreign key constraint to UserCompany.
I have a trigger on UserInfo which inserts/updates/deletes rows into UserInfoComputed
Here is my UserInfoComputed table:
CREATE TABLE [dbo].[UserInfoComputed ](
[id] AS (CONVERT([bigint],replace([law_id],'LAW',''),(0))) PERSISTED NOT NULL,
[company_id] [varchar](12) NOT NULL,
[first_name] [varchar](30) NOT NULL,
[last_name] [varchar](30) NOT NULL,
[law_id] [varchar](12) NOT NULL,
[type] [smallint] NULL,
[dtype] AS (case [TYPE] when (1) then 'Corporate' else 'Non-Corporate' end) PERSISTED NOT NULL,
CONSTRAINT [PK_UserInfoComputed] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[UserInfoComputed] WITH CHECK ADD CONSTRAINT [FK668581C04AA07B12] FOREIGN KEY([company_id])
REFERENCES [dbo].[UserCompany] ([id])
GO
Here is my UserInfo table
CREATE TABLE [dbo].[UserInfo](
[ID] [varchar](12) NOT NULL,
[CompanyID] [varchar](12) NULL,
[Status] [char](4) NULL,
[FirstName] [varchar](30) NOT NULL,
[LastName] [varchar](30) NOT NULL,
CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Here is the UserCompany table
CREATE TABLE [dbo].[UserCompany](
[ID] [varchar](12) NOT NULL,
[Name] [varchar](100) NULL,
[ShortName] [varchar](25) NULL,
[Type] [smallint] NULL,
CONSTRAINT [PK_UserCompany] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
The type values are either 1 or 2 or 3
Here is my trigger on UserInfo table
CREATE TRIGGER [dbo].[ReconcileUserInfoComputed]
ON [dbo].[UserInformation]
AFTER INSERT,DELETE,UPDATE
AS
IF ##ROWCOUNT = 0 -- exit trigger when zero records affected
BEGIN
RETURN
END
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
--UPDATE
UPDATE [dbo].[UserInformationComputed]
SET -- use new values from inserted
first_name = (SELECT FirstName FROM inserted),
last_name = (SELECT LastName FROM inserted),
law_id = (SELECT ID FROM inserted)
WHERE law_id = (SELECT ID FROM deleted)
END
ELSE
BEGIN
--INSERT
INSERT INTO [dbo].[UserInfoComputed] (first_name,last_name, law_id)
SELECT FirstName, LastName, ID FROM inserted
END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
--DELETE
DELETE FROM [dbo].[UserInfoComputed]
WHERE law_id = (SELECT id FROM deleted)
END
GO
Is there a way to insert or update type value from UserCompany into UserInfoComputed table in ReconcileUserInfoComputed trigger?

Related

Difference with nolock and readpast in SQL server 2016

I am updating a table Hr.employees for a single record in a transaction in one query window
Begin Tran A
update hr.Employees
set lastname = 'davis'
where empid=1
In other query window i am running two select statements without a transaction
select count(*) from hr.Employees with(nolock)
select count(*) from hr.Employees with(readpast)
Both of them returning 9, whereas readpast should return 8 as it removes dirty read when returning data.
CREATE TABLE [HR].[Employees](
[empid] [int] IDENTITY(1,1) NOT NULL,
[lastname] [nvarchar](20) NOT NULL,
[firstname] [nvarchar](10) NOT NULL,
[title] [nvarchar](30) NOT NULL,
[titleofcourtesy] [nvarchar](25) NOT NULL,
[birthdate] [datetime] NOT NULL,
[hiredate] [datetime] NOT NULL,
[address] [nvarchar](60) NOT NULL,
[city] [nvarchar](15) NOT NULL,
[region] [nvarchar](15) NULL,
[postalcode] [nvarchar](10) NULL,
[country] [nvarchar](15) NOT NULL,
[phone] [nvarchar](24) NOT NULL,
[mgrid] [int] NULL,
CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED
(
[empid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [HR].[Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_Employees] FOREIGN KEY([mgrid])
REFERENCES [HR].[Employees] ([empid])
GO
ALTER TABLE [HR].[Employees] CHECK CONSTRAINT [FK_Employees_Employees]
GO
ALTER TABLE [HR].[Employees] WITH CHECK ADD CONSTRAINT [CHK_birthdate] CHECK (([birthdate]<=getdate()))
GO
ALTER TABLE [HR].[Employees] CHECK CONSTRAINT [CHK_birthdate]
GO
CREATE NONCLUSTERED INDEX [idx_nc_lastname] ON [HR].[Employees]
(
[lastname] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [idx_nc_postalcode] ON [HR].[Employees]
(
[postalcode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Trigger causing primary key violation

We have a trigger that we are trying to update so that when a record is updated, the trigger will update a second table. When we activate the change, we get an error
Violation of PRIMARY KEY contstraint 'KPRIMARY_SO_SalesOrderHeader". Cannot insert duplicate key in object 'dbo.SO_SalesOrderHeader". The duplicate key is XXXXXX.
I'm really confused by this because I don't see in the trigger where we are trying to insert a key.
ALTER Trigger [dbo].[SO_SALESORDERHEADER_onOrderChange]
ON [dbo].[SO_SalesOrderHeader]
FOR INSERT, UPDATE
AS
SET NOCOUNT ON;
--+
INSERT INTO dbo.OrderUpdateQueue (SourceId, OrderNumber, Action)
SELECT DISTINCT
N'SO', Inserted.SALESORDERNO, N'U'
FROM
Inserted
LEFT JOIN
dbo.OrderUpdateQueue ON (Inserted.SALESORDERNO = OrderUpdateQueue.OrderNumber)
AND (OrderUpdateQueue.SourceID = N'SO')
AND (OrderUpdateQueue.Action = N'U')
WHERE
(OrderUpdateQueue.[Key] IS NULL)
AND (Inserted.SALESORDERNO IS NOT NULL);
--+ New Trigger Stuff
UPDATE MO
SET MO.[ShipDate] = I.ShipExpireDate
FROM [BACKEND_db].[dbo].[Order] MO
INNER JOIN Inserted I ON I.SalesOrderNo = MO.OrderId
WHERE MO.ShipDate <> I.ShipExpireDate;
CREATE TABLE [dbo].[SO_SalesOrderHeader](
[SalesOrderNo] [varchar](7) NOT NULL
CONSTRAINT [KPRIMARY_SO_SalesOrderHeader] PRIMARY KEY CLUSTERED
(
[SalesOrderNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[OrderUpdateQueue](
[Key] [int] IDENTITY(1,1) NOT NULL,
[SourceId] [nvarchar](50) NOT NULL,
[OrderNumber] [nvarchar](50) NOT NULL,
[Action] [nchar](1) NOT NULL,
CONSTRAINT [PK_OrderUpdateQueue] PRIMARY KEY CLUSTERED
(
[Key] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [BACKEND_db]
CREATE TABLE [dbo].[Order](
[Key] [int] IDENTITY(1,1) NOT NULL,
[OrderId] [nvarchar](10) NULL,
[ShipDate] [datetime] NULL
CONSTRAINT [PK_MasOrder] PRIMARY KEY CLUSTERED
(
[Key] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
How you do not post the schema of OrderUpdateQueue table, I believe the pk is the OrderNumber field. You can try to change your trigger to:
ALTER Trigger [dbo].[SO_SALESORDERHEADER_onOrderChange]
ON [dbo].[SO_SalesOrderHeader]
FOR INSERT, UPDATE
AS
SET NOCOUNT ON;
--+
INSERT INTO dbo.OrderUpdateQueue (SourceId, OrderNumber, Action)
SELECT DISTINCT
N'SO', Inserted.SALESORDERNO, N'U'
FROM
Inserted
WHERE not exists (SELECT 1 FROM dbo.OrderUpdateQueue where Inserted.SALESORDERNO = OrderUpdateQueue.OrderNumber)
UPDATE MO
SET MO.[ShipDate] = I.ShipExpireDate
FROM [BACKEND_db].[dbo].[Order] MO
INNER JOIN Inserted I ON I.SalesOrderNo = MO.OrderId
WHERE MO.ShipDate <> I.ShipExpireDate;

Figure Out Which OrderIDs are 0$ Payment Totals

I am in need to some help writing a SQL 2012 query that will help me find and mark orderID's that are a $0.00 payments due to reversal(s)
So far I have:
Select Distinct a.orderID, a.orderPaid,
(Select SUM((c1.linePrice + c1.lineShippingCost + c1.lineTaxCost + c1.lineOptionCost) * c1.lineQuantity)
From vwSelectOrderLineItems c1 Where c1.orderID = a.orderID) As OrderAmount,
(Select SUM(b1.payAmount) FROM vwSelectOrderPayments b1 Where b1.orderID = a.orderID) as Payment,
1 As IsReversal
From vwSelectOrders a
Left Outer Join vwSelectOrderPayments b On b.orderID = a.orderID
Where b.payValid = 1 AND a.orderPaid = 0
Which is returning me some $0 payments on some orders. When I query that payment table with the orderID of these records, I can see that 2 payments were posted... 1 the original payment, 2 the reversal.
How Can I flag the Orders that are $0 payments?
Oders
CREATE TABLE [dbo].[TblOrders](
[orderID] [bigint] IDENTITY(1000,1) NOT NULL,
[orderPaid] [bit] NOT NULL,
[orderPaidOn] [datetime] NULL
CONSTRAINT [PK_TblOrders] PRIMARY KEY CLUSTERED
(
[orderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrders] ADD CONSTRAINT [DF__TblOrders__order__1975C517] DEFAULT ((0)) FOR [orderPaid]
Order Line Items
CREATE TABLE [dbo].[TblOrderLineItems](
[lineID] [bigint] IDENTITY(1,1) NOT NULL,
[orderID] [bigint] NOT NULL,
[lineQuantity] [int] NOT NULL,
[linePrice] [money] NOT NULL,
[lineShippingCost] [money] NOT NULL,
[lineTaxCost] [money] NOT NULL,
[lineOptionCost] [money] NOT NULL,
CONSTRAINT [PK_TblOrderLineItems] PRIMARY KEY CLUSTERED
(
[lineID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineShippingCost] DEFAULT ((0)) FOR [lineShippingCost]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineTaxCost] DEFAULT ((0)) FOR [lineTaxCost]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineOptionCost] DEFAULT ((0)) FOR [lineOptionCost]
GO
Order Payments
CREATE TABLE [dbo].[TblOrderPayments](
[paymentID] [bigint] IDENTITY(1,1) NOT NULL,
[orderID] [bigint] NOT NULL,
[payAmount] [money] NOT NULL,
[payPosted] [datetime] NOT NULL,
[payValid] [bit] NOT NULL,
CONSTRAINT [PK_TblOrderPayments] PRIMARY KEY CLUSTERED
(
[paymentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrderPayments] ADD CONSTRAINT [DF_TblOrderPayments_payValid] DEFAULT ((0)) FOR [payValid]
GO
Views
CREATE VIEW [dbo].[vwSelectOrderLineItems] AS
SELECT linePrice, lineShippingCost, lineTaxCost, lineOptionCost, lineQuantity
FROM [dbo].[TblOrderLineItems]
CREATE VIEW [dbo].[vwSelectOrderPayments] AS
SELECT paymentID, orderID, payAmount, payValid
FROM dbo.TblOrderPayments
CREATE VIEW [dbo].[vwSelectOrders] AS
SELECT orderID , orderPaid
FROM dbo.TblOrders
Note
I cannot change the table structure
SELECT distinct a.orderid,
a.orderPaid,
c.OrderAmount
d.Payment
From vwSelectOrders AS a
INNER JOIN ( Select SUM((linePrice + lineShippingCost + lineTaxCost + lineOptionCost) * lineQuantity) As orderAmount,OrderID
From vwSelectOrderLineItems group by orderid) AS C on c.orderID = a.orderID
INNER JOIN (Select SUM(payAmount) as Payment,orderID FROM vwSelectOrderPayments WHERE isnull(SUM(PayAmount),0) > 0 GROUP BY OrderID) AS d ON d.orderID = a.orderID
Left Outer Join vwSelectOrderPayments b On b.orderID = a.orderID
Where b.payValid = 1 AND a.orderPaid = 0 AND
This is a better query as you do not have to us a correlated subquery. Correlated queries are when a subquery references an outerquery row. This isn't optimal because every row the outerquery runs the correlated subquery will execute. Once you give us table definitions we can probably fix the overall data return of your query.

Problems understanding intermittent inconsistencies when loading data with SSIS package

The problem
During the passed few months the below described procedure has worked without any problems a vast majority of the times it has run (on 2008 r2). We have, however, three instances of incorrectly connected data. The question is, what is causing this and how do I remedy it?
DATA_PreImp
sourceid col01 col02 col03 col04 col...
100001 John Smith
100002 Calvin Klein
100003 Peter Parker
100004 Moe Greene
Usually the rendered result is that the attribute is connected to the Items_Main correctly but sometimes (less than 1%) the order is scrambled so that the value of col01 is not connected to the same Items_Main as the value of the rest of the columns.
Any insights as to what is causing this would be most appreciated.
The data moving procedure
We have an SSIS package that transfers data from a flat table called DATA_PreImp to a structure consisting of three related tables (attribute based).
Items_Main should contains one row for each row in DATA_PreImp
Items_Featurevalues contains one row for each column value of a row in DATA_PreImp
Items_MainRel contains the connection between Items_Main and Items_FeatureValues
The first step in the SSIS package inserts the data from DATA_PreImp to Items_Main and inserts the generated identifier into the TARGET_ID column in the empty DATA_PreImpMappingTMP table.
insert into items_main(creationdate, status)
output inserted.itemid into DATA_PreImpMappingTMP(TARGET_ID)
select getdate(), '0' from data_preimp
order by sourceid asc;
The second step in the SSIS package fill the Items_MainRel table with TARGET_ID (Itemid originally) and an identifier for the feature (in this case a 5).
insert into items_mainrel(itemid, featureid)
output inserted.itemrelid into DATA_PreImpMapping2TMP(INDREL_ID)
select TARGET_ID, 5 from DATA_PreImpMappingTMP
order by TARGET_ID asc;
The third step is to fill the SOURCE_ID column in the DATA_PreImpMapping2TMP table with the SOURCE_ID from DATA_PreImp.
with cte as (select sourceid, row_number() over (order by sourceid asc) as row from data_preimp)
update m set m.SOURCE_ID = s.sourceid, m.FEAT_ID = 5
from DATA_PreImpMapping2TMP as m
join cte as s on s.row = m.ROW;
The last step is to fill the Items_FeatureValues table with data from DATA_PreImpMapping2TMP and DATA_PreImp.
insert into items_featurevalues(itemrelid, languageid, fnvarchar)
select DATA_PreImpMapping2TMP.INDREL_ID, 0, data_preimp.col01
from DATA_PreImpMapping2TMP
join data_preimp on (DATA_PreImpMapping2TMP.SOURCE_ID = data_preimp.sourceid)
where FEAT_ID = 5
Data table structure
Here is what is needed to create the scenario:
CREATE TABLE [dbo].[DATA_PreImp](
[sourceid] [bigint] IDENTITY(1,1) NOT NULL,
[col01] [nvarchar](500) NULL,
[col02] [nvarchar](500) NULL,
[col03] [nvarchar](500) NULL,
[col04] [nvarchar](500) NULL,
[col05] [nvarchar](500) NULL,
[col06] [nvarchar](500) NULL,
[col07] [nvarchar](500) NULL,
[col08] [nvarchar](500) NULL,
[col09] [nvarchar](500) NULL,
[col10] [nvarchar](500) NULL,
CONSTRAINT [PK_DATA_PreImp] PRIMARY KEY CLUSTERED
(
[sourceid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[DATA_PreImpMappingTMP](
[ROW] [int] IDENTITY(1,1) NOT NULL,
[TARGET_ID] [int] NULL,
PRIMARY KEY CLUSTERED
(
[ROW] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Items_Main](
[Itemid] [int] IDENTITY(1,1) NOT NULL,
[creationDate] [smalldatetime] NOT NULL,
[status] [int] NOT NULL,
[purchdate] [smalldatetime] NULL,
[logindate] [smalldatetime] NULL,
CONSTRAINT [PK_Items_Main] PRIMARY KEY CLUSTERED
(
[Itemid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[DATA_PreImpMapping2TMP](
[ROW] [int] IDENTITY(1,1) NOT NULL,
[SOURCE_ID] [int] NULL,
[INDREL_ID] [int] NULL,
[FEAT_ID] [int] NULL,
PRIMARY KEY CLUSTERED
(
[ROW] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Items_Features](
[featureId] [int] IDENTITY(1,1) NOT NULL,
[featureRef] [varchar](15) NOT NULL,
[featureName] [varchar](50) NOT NULL,
[creationDate] [smalldatetime] NOT NULL,
[status] [int] NOT NULL,
[fieldType] [varchar](50) NOT NULL,
[featureType] [int] NOT NULL,
[featureDesc] [varchar](500) NULL,
CONSTRAINT [PK_Items_Features] PRIMARY KEY CLUSTERED
(
[featureId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
CREATE TABLE [dbo].[Items_MainRel](
[ItemRelId] [int] IDENTITY(1,1) NOT NULL,
[Itemid] [int] NOT NULL,
[featureId] [int] NOT NULL,
CONSTRAINT [PK_Items_MainRel] PRIMARY KEY CLUSTERED
(
[ItemRelId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Items_FeatureValues](
[valueId] [int] IDENTITY(1,1) NOT NULL,
[ItemRelId] [int] NOT NULL,
[languageId] [int] NOT NULL,
[FnVarChar] [nvarchar](250) NULL,
[FInt] [int] NULL,
[FImage] [int] NULL,
[FNText] [ntext] NULL,
[FSmallDateTime] [smalldatetime] NULL,
CONSTRAINT [PK_Items_FeatureValues] PRIMARY KEY CLUSTERED
(
[valueId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Items_MainRel] WITH CHECK ADD CONSTRAINT [FK_Items_MainRel_Items_Features] FOREIGN KEY([featureId])
REFERENCES [dbo].[Items_Features] ([featureId])
GO
ALTER TABLE [dbo].[Items_MainRel] CHECK CONSTRAINT [FK_Items_MainRel_Items_Features]
GO
ALTER TABLE [dbo].[Items_MainRel] WITH CHECK ADD CONSTRAINT [FK_Items_MainRel_Items_Main] FOREIGN KEY([Itemid])
REFERENCES [dbo].[Items_Main] ([Itemid])
GO
ALTER TABLE [dbo].[Items_MainRel] CHECK CONSTRAINT [FK_Items_MainRel_Items_Main]
GO
ALTER TABLE [dbo].[Items_FeatureValues] WITH CHECK ADD CONSTRAINT [FK_Items_FeatureValues_Items_MainRel] FOREIGN KEY([ItemRelId])
REFERENCES [dbo].[Items_MainRel] ([ItemRelId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Items_FeatureValues] CHECK CONSTRAINT [FK_Items_FeatureValues_Items_MainRel]
GO
INSERT INTO DATA_PreImp (col01,col02,col03,col04)
VALUES('John', 'Smith', '1964', 'NewYork'),
('Calvin', 'Klein', '1960', 'Washington D. C.'),
('Peter', 'Parker', '1974', 'Losangles'),
('Moe', 'Greene', '1928', 'Lasvegas')
INSERT INTO Items_Features (featureRef, featureName, creationDate, [status], fieldType, featureType, featureDesc)
VALUES ('firstname','First_Name', GETDATE(), 0, 'FnVarChar', 3, 'FirstName'),
('lastname','Last_Name', GETDATE(), 0, 'FnVarChar', 3, 'LastName'),
('Birth','Birth', GETDATE(), 0, 'FnVarChar', 3, 'Birth'),
('City','City', GETDATE(), 0, 'FnVarChar', 3, 'City')
The problem was the computed column CUST_CD. After a lot of researching, it seems that the BULK INSERT does not like complex computed types (see Using SQL Server spatial types in SSIS data load). The solution is to removed the computed column and just make it a varchar(20) NULL. Then I created a new Execute SQL Task that updates any NULL rows with the computed value.

How should I migrate this data into these Sql Server tables?

I wish to migrate some data from a single table into these new THREE tables.
Here's my destination schema:
Notice that I need to insert into the first Location table .. grab the SCOPE_IDENTITY() .. then insert the rows into the Boundary and Country tables.
The SCOPE_IDENTITY() is killing me :( meaning, I can only see a way to do this via CURSORS. Is there a better alternative?
UPDATE
Here's the scripts for the DB Schema....
Location
CREATE TABLE [dbo].[Locations](
[LocationId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[OriginalLocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
Country
CREATE TABLE [dbo].[Locations_Country](
[IsoCode] [nchar](2) NOT NULL,
[LocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations_Country] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Locations_Country] WITH CHECK ADD CONSTRAINT [FK_Country_inherits_Location] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Locations_Country] CHECK CONSTRAINT [FK_Country_inherits_Location]
GO
Boundary
CREATE TABLE [dbo].[Boundaries](
[LocationId] [int] NOT NULL,
[CentrePoint] [varbinary](max) NOT NULL,
[OriginalBoundary] [varbinary](max) NULL,
[LargeReducedBoundary] [varbinary](max) NULL,
[MediumReducedBoundary] [varbinary](max) NULL,
[SmallReducedBoundary] [varbinary](max) NULL,
CONSTRAINT [PK_Boundaries] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Boundaries] WITH CHECK ADD CONSTRAINT [FK_LocationBoundary] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Boundaries] CHECK CONSTRAINT [FK_LocationBoundary]
GO
I don't see a need for SCOPE_IDENTITY or cursors if you approach the data in order of the parent/child relationship:
INSERT INTO LOCATION
SELECT t.name,
t.originallocationid
FROM ORIGINAL_TABLE t
GROUP BY t.name, t.originallocationid
INSERT INTO COUNTRY
SELECT DISTINCT
t.isocode,
l.locationid
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
INSERT INTO BOUNDARY
SELECT DISTINCT
l.locationid,
t.centrepoint,
t.originalboundary,
t.largereducedboundary,
t.mediumreducedboundary,
t.smallreducedboundary
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
After loading your Location table you could create a query that joins Location with your source single table. The join criteria would be the natural key (is that the Name column?) and it would return the new LocationId along with the Boundary data. The results would inserted into the new Boundary table.