I was trying to extend the above link http://blogs.msdn.com/b/biztalkcpr/archive/2009/10/05/inserting-parent-child-records-with-identity-column-using-wcf-sql-adapter-in-one-transaction.aspx#comments
My problem is :
I have three table....the first two tables have id as IDENTITY... I need to get the id of first table in 2nd table
Then I need to get id of 1st and 2nd table in 3rd table ..... I was able to get id of first table into 2nd table
But I'm not able to get id of 2nd table into 3rd table...........I am using WCF SQL adapter to consume the stored procedure and my stored procedure looks like this
CREATE Procedure [dbo].[InsertHeader]
(
#parHeader As Header READONLY,
#parHeader_Details As HeaderDetails READONLY,
#parHeader_Details1 As HeaderDetails1 READONLY
)
AS
SET NOCOUNT ON
BEGIN
DECLARE #id int, #id1 int
INSERT INTO EDI834_5010_Header([File_Name_EDI834], [ST01], [ST02], [ST03],
[BGN01__TransactionSetPurposeCode],
[BGN02__TransactionSetIdentifierCode],
[BGN03__TransactionSetCreationDate],
[BGN04__TransactionSetCreationTime],
[BGN08__ActionCode], [SE01], [SE02])
SELECT
[File_Name_EDI834], [ST01], [ST02], [ST03],
[BGN01__TransactionSetPurposeCode], [BGN02__TransactionSetIdentifierCode],
[BGN03__TransactionSetCreationDate], [BGN04__TransactionSetCreationTime],
[BGN08__ActionCode], [SE01], [SE02]
FROM #parHeader;
SET #id = ##IDENTITY;
INSERT INTO EDI834_5010_2000([Header_Id], [INS01__InsuredIndicator],
[INS02__IndividualRelationshipCode],
[INS03__MaintenanceTypeCode],
[INS04__MaintenanceReasonCode],
[INS05__BenefitStatusCode])
SELECT #id, [INS01__InsuredIndicator], [INS02__IndividualRelationshipCode],
[INS03__MaintenanceTypeCode], [INS04__MaintenanceReasonCode],
[INS05__BenefitStatusCode]
FROM #parHeader_Details;
SET #id1 = ##IDENTITY;
INSERT INTO EDI834_5010_2300Loop([Id_Header_Id], [Id_Loop2000],
[HD01_MaintenanceTypeCode], [HD03_InsuranceLineCode],
[HD04_PlanCoverageDescription])
SELECT #id, #id1,
HD01_MaintenanceTypeCode, HD03_InsuranceLineCode,
HD04_PlanCoverageDescription
FROM #parHeader_Details1;
RETURN #id1;
END
What do I need to change in my stored procedure to get the id of 2nd table into 3rd....... there are so many looping in xml so I need to get the appropriate ids in 3rd table
And my data looks like this
<Header details>
<Header_Details1> data </Header_Details>
<Header_Details1> data </Header_Details>
<Header_Details1> data </Header_Details>
<Header_details>
<Header details>
<Header_Details1> data </Header_Details>
<Header_Details1> data </Header_Details>
<Header_Details1> data </Header_Details>
<Header_details>
Well, your main problem is: you're not just inserting a single row - but a whole bunch of rows!
So while you can use ##IDENTITY to get the last inserted identity value (btw: I would recommend using SCOPE_IDENTITY() instead - see here as for why) - this will only work for a single row!
What you need is a mechanism to output multiple inserted identities - use the OUTPUT clause:
DECLARE #InsertedIDs TABLE (ID1 INT, ID2 INT)
INSERT INTO EDI834_5010_Header(......)
OUTPUT Inserted.ID INTO #InsertedIDs(ID1)
SELECT
.......
FROM #parHeader;
For the first statement, this will output all inserted identity values into the table variable #InsertedIDs.
Now for your second table - is there any column that you can relate the first and second inserted ID's by?? You would need to capture the inserted identity values from the second INSERT into the same table variable, but you need to somehow know which ID1 to associate with with ID2 - and I quite frankly don't see how that would be done in your statements.....
But in the end, you would have a table variable with n rows of (ID1, ID2) which you can then use to insert into your third table.
Related
I'm currently working on a stored procedure in SQL Server 2012 using T-SQL. My problem: I have several SWOTs (e.g. for a specific client) holding several SWOTParts (strengths, weaknesses, opportunities, and threats). I store the values in a table Swot as well as in another table SwotPart.
My foreign Key link is SwotId in SwotPart, thus 1 Swot can hold N SwotParts. Hence, I store the SwotId in every SwotPart.
I can have many Swots and now need to set the SwotId correctly to create the foreign key. I set the SwotId using SCOPE_IDENTITY() unfortunately it only takes the last SwotId from the DB.I'm looking for something like a for loop to increment the SwotId after each insert on the 1st insert.
DECLARE #SwotId INT = 1;
-- 1st insert
SET NOCOUNT ON
INSERT INTO [MySchema].[SWOT]([SwotTypeId]) // Type can be e.g. a sepcific client
SELECT SwotTypeId
FROM #SWOTS
SET #SwotId = SCOPE_IDENTITY(); // currently e.g. 7, but should increment: 1, 2, 3...
-- 2nd insert
SET NOCOUNT ON
INSERT INTO [MySchema].[SwotPart]([SwotId], [FieldTypeId], [Label]) // FieldType can be e.g. Streangh
SELECT #SwotId, FieldTypeId, Label
FROM #SWOTPARTS
Do you know how to solve this issue? What could I use instead of SCOPE_IDENTITY()?
Thank you very much!
You can output the inserted rows into a temporary table, then join your #swotparts to the temporary table based on the natural key (whatever unique column set ties them together beyond the SwotId). This would solve the problem with resorting to loops or cursors, while also overcoming the obstacle of doing a single swot at a time.
set nocount, xact_abort on;
create table #swot (SwotId int, SwotTypeId int);
insert into MySchema.swot (SwotTypeId)
output inserted.SwotId, inserted.SwotTypeId into #swot
select SwotTypeId
from #swots;
insert into MySchema.SwotPart(SwotId, FieldTypeId, Label)
select s.SwotId, p.FieldTypeId, p.Label
from #swotparts p
inner join #swot s
on p.SwotTypeId = p.SwotTypeId;
Unfortunately I cant comment so I`ll leave you an answer hopefully to clarify some things:
Since you need to create the correct foreign key I don`t understand
why do you need to increment a value instead of using the id inserted
into the SWOT table.
I suggest returning the inserted id using the SCOPE_IDENTITY right after the insert statement and use it for you insert into the swot parts (there is plenty of info about it and how to use it)
DECLARE #SwotId INT;
-- 1st insert
INSERT INTO [MySchema].[SWOT]([SwotTypeId]) // Type can be e.g. a sepcific client
SET #SwotId = SCOPE_IDENTITY();
-- 2nd insert
INSERT INTO [MySchema].[SwotPart]([SwotId], [FieldTypeId], [Label])
SELECT #SwotId, FieldTypeId, Label
FROM #SWOTPARTS
I have 2 tables ProductSize and Product.
Product table:
ProductID ProductCode ProductSizeID
Product Size table:
ProductSizeID PackperCase ItemsperCase ItemSize
I have a stored procedure which populates both these tables, however I can't populate the Products table without populating the Product Size table (as I need the productsizeID).
How can I tackle this?
I need something which shows the last ID I just inserted into the Productsize table. The stored procedure inserts 1 record at a time, but I don't really want to use MAX() to get the ID because other things may be going on in the database.
You need to first insert the row into ProductSize and get the ID back:
INSERT INTO dbo.ProductSize(PackPerCase, ItemsPerCase, ItemSize)
VALUES( ....., ....., .....);
DECLARE #NewID INT = SCOPE_IDENTITY();
and then use that in your second insert into the Products table:
INSERT INTO dbo.Products(ProductCode, ProductSizeID)
VALUES( ....., #NewID);
and you're done!
I have a Oracle trigger and I need to create column after insert rows to first table.
So.. In my scenario:
When some record inserted into NEWS_TBL and i need to get that(in here i get it via last inserted record) and i need to get the NAME from the NEWS_TBL and returning value to NewsName variable and that returned value inserted to the NEWS_TYPE_TBL as a Column.
Below code is not working. can anyone pls give me a solution for this.
MyCode
BEFORE DELETE OR INSERT OR UPDATE
ON NEWS.NEWS_FIRST
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
NewsName varchar2(50);
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
EXECUTE IMMEDIATE
'select *
from ( select a.NAME,a.ID, max(ID) over () as max_pk
from NEWS_TBL a)
where ID = max_pk
RETURNING NAME INTO NewsName';
'ALTER TABLE NEWS_TYPE_TBL ADD [NewsName] NUMBER(50) NULL';
// I want to add returning ticket name to here from 1st query.
END trigNews;
/
I'm working on an sp that inserts data into two tables. The two tables are featured and featured type, both have a pk featuredid that gets auto incremented each time something is added. I have:
insert into featured
(title,text,imageURL, priority )
values
(#title,#text,#imageURL, #priority),
insert into featuredtype
(loginPage, indexPage, mobilePage)
values
(#loginPage, #indexPage, #mobilePage)
However, it appears this is not the correct method for inserting into two tables from one sp.
You need to get rid of the comma after #priority),
You can replace it with a semi-colon ; or nothing at all, so
create proc yourproc
(
-- parameter definitions here
)
as
begin
insert into featured
(title,text,imageURL, priority )
values
(#title,#text,#imageURL, #priority)
insert into featuredtype
(loginPage, indexPage, mobilePage)
values
(#loginPage, #indexPage, #mobilePage)
end
You can even try with
insert into featured (title,text,imageURL, priority )
select #title,#text,#imageURL, #priority
insert into featuredtype (loginPage, indexPage, mobilePage)
select #loginPage, #indexPage, #mobilePage
Here is my "upsert" code:
UPDATE LastTicket SET LastTicketNumber=LastTicketNumber+1
OUTPUT INSERTED.LastTicketNumber WHERE CategoryId='1';
IF ##ROWCOUNT=0 INSERT INTO LastTicket (CategoryId,LastTicketNumber)
OUTPUT INSERTED.LastTicketNumber VALUES ('1','2')
So, when the row exists, it successefully updates, the OUTPUT returns the new, incremented LastTicketNumber.
On the other hand, when the row does not exist, the sql server successefully creates it and populates with the data I am passing to SqlCommand (1,2). So, it creates the row, but returns null. Meaning nothing! Why is that? And why when i replace the "INSERTED.LastTicketNumber" with the "INSERTED.CategoryId" is BEGINS to return not-null, the category id. Why is that? And how to return what I need?
The table has only these two columns and nonclustered primary composite key on both of them.
(MSSQL 2008)
If no row exists in the table, the first time the batch runs it will return two result sets - the first being empty (because there is no row to update) and the second containing the inserted Id.
Perhaps you are seeing the first result set and not the second.
Try the following:
DECLARE #t table (LastTicketNumber int)
UPDATE LastTicket SET LastTicketNumber=LastTicketNumber+1
OUTPUT INSERTED.LastTicketNumber INTO #t (LastTicketNumber) WHERE CategoryId='1';
IF ##ROWCOUNT=0 INSERT INTO LastTicket (CategoryId,LastTicketNumber)
OUTPUT INSERTED.LastTicketNumber INTO #t (LastTicketNumber) VALUES ('1','2')
select LastTicketNumber from #t