Using temporary table data to update first table, then use identity from first table and same temp data to...












1















This question already has an answer here:




  • Is it possible to for SQL Output clause to return a column not being inserted?

    2 answers




I have a temporary table that contains data that needs to be inserted on two different tables, the temp is defined as:



CREATE TABLE #PaymentHistory
(
amount INT,
ImportantValue INT
)


then I have a first table called PaymentHistory which is defined as:



CREATE TABLE PaymentHistory
(
PaymentKey BIGINT IDENTITY,
amount INT
)


Finally I have a second table called SecondTable which is defined as:



CREATE TABLE SecondTable
(
PaymentKey INT,
ImportantValue INT
)


So I need to use the data on #PaymentHistory to insert on PaymentHistory, then use the identity generated on that table in the PaymentKey field to insert into SecondTable using both the PaymentKey identity and the ImportantValue on the #PaymentHistory table



So, the only table that should begin with data is #PaymentHistory, let's say I have the following records on that table:



Amount          |      ImportantValue
10 | 2
15 | 5
9 | 21


So the end result of the insert I'm after should yield the following results when I select from:



PaymentHistory:



PaymentKey      |      Amount
1 | 10
2 | 15
3 | 9


SecondTable:



PaymentKey      |      ImportantValue
1 | 2
2 | 5
3 | 21


I cannot modify the schema of PaymentHistory table, but I could alter the temporary table or the SecondTable if needed



I tried using OUTPUT to get both the identity and the ImportantValue, but since the ImportantValue is on the source table, I cannot get it with OUTPUT. I can't think of another way to link the data correctly, any help will be much appreciated










share|improve this question















marked as duplicate by Damien_The_Unbeliever sql-server
Users with the  sql-server badge can single-handedly close sql-server questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 21 at 14:42


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Sample data and expected results might explain what you're after here.
    – Larnu
    Nov 20 at 20:35












  • Alright, I'll add some sample data, thanks
    – Santiago San Martin
    Nov 20 at 20:36
















1















This question already has an answer here:




  • Is it possible to for SQL Output clause to return a column not being inserted?

    2 answers




I have a temporary table that contains data that needs to be inserted on two different tables, the temp is defined as:



CREATE TABLE #PaymentHistory
(
amount INT,
ImportantValue INT
)


then I have a first table called PaymentHistory which is defined as:



CREATE TABLE PaymentHistory
(
PaymentKey BIGINT IDENTITY,
amount INT
)


Finally I have a second table called SecondTable which is defined as:



CREATE TABLE SecondTable
(
PaymentKey INT,
ImportantValue INT
)


So I need to use the data on #PaymentHistory to insert on PaymentHistory, then use the identity generated on that table in the PaymentKey field to insert into SecondTable using both the PaymentKey identity and the ImportantValue on the #PaymentHistory table



So, the only table that should begin with data is #PaymentHistory, let's say I have the following records on that table:



Amount          |      ImportantValue
10 | 2
15 | 5
9 | 21


So the end result of the insert I'm after should yield the following results when I select from:



PaymentHistory:



PaymentKey      |      Amount
1 | 10
2 | 15
3 | 9


SecondTable:



PaymentKey      |      ImportantValue
1 | 2
2 | 5
3 | 21


I cannot modify the schema of PaymentHistory table, but I could alter the temporary table or the SecondTable if needed



I tried using OUTPUT to get both the identity and the ImportantValue, but since the ImportantValue is on the source table, I cannot get it with OUTPUT. I can't think of another way to link the data correctly, any help will be much appreciated










share|improve this question















marked as duplicate by Damien_The_Unbeliever sql-server
Users with the  sql-server badge can single-handedly close sql-server questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 21 at 14:42


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Sample data and expected results might explain what you're after here.
    – Larnu
    Nov 20 at 20:35












  • Alright, I'll add some sample data, thanks
    – Santiago San Martin
    Nov 20 at 20:36














1












1








1








This question already has an answer here:




  • Is it possible to for SQL Output clause to return a column not being inserted?

    2 answers




I have a temporary table that contains data that needs to be inserted on two different tables, the temp is defined as:



CREATE TABLE #PaymentHistory
(
amount INT,
ImportantValue INT
)


then I have a first table called PaymentHistory which is defined as:



CREATE TABLE PaymentHistory
(
PaymentKey BIGINT IDENTITY,
amount INT
)


Finally I have a second table called SecondTable which is defined as:



CREATE TABLE SecondTable
(
PaymentKey INT,
ImportantValue INT
)


So I need to use the data on #PaymentHistory to insert on PaymentHistory, then use the identity generated on that table in the PaymentKey field to insert into SecondTable using both the PaymentKey identity and the ImportantValue on the #PaymentHistory table



So, the only table that should begin with data is #PaymentHistory, let's say I have the following records on that table:



Amount          |      ImportantValue
10 | 2
15 | 5
9 | 21


So the end result of the insert I'm after should yield the following results when I select from:



PaymentHistory:



PaymentKey      |      Amount
1 | 10
2 | 15
3 | 9


SecondTable:



PaymentKey      |      ImportantValue
1 | 2
2 | 5
3 | 21


I cannot modify the schema of PaymentHistory table, but I could alter the temporary table or the SecondTable if needed



I tried using OUTPUT to get both the identity and the ImportantValue, but since the ImportantValue is on the source table, I cannot get it with OUTPUT. I can't think of another way to link the data correctly, any help will be much appreciated










share|improve this question
















This question already has an answer here:




  • Is it possible to for SQL Output clause to return a column not being inserted?

    2 answers




I have a temporary table that contains data that needs to be inserted on two different tables, the temp is defined as:



CREATE TABLE #PaymentHistory
(
amount INT,
ImportantValue INT
)


then I have a first table called PaymentHistory which is defined as:



CREATE TABLE PaymentHistory
(
PaymentKey BIGINT IDENTITY,
amount INT
)


Finally I have a second table called SecondTable which is defined as:



CREATE TABLE SecondTable
(
PaymentKey INT,
ImportantValue INT
)


So I need to use the data on #PaymentHistory to insert on PaymentHistory, then use the identity generated on that table in the PaymentKey field to insert into SecondTable using both the PaymentKey identity and the ImportantValue on the #PaymentHistory table



So, the only table that should begin with data is #PaymentHistory, let's say I have the following records on that table:



Amount          |      ImportantValue
10 | 2
15 | 5
9 | 21


So the end result of the insert I'm after should yield the following results when I select from:



PaymentHistory:



PaymentKey      |      Amount
1 | 10
2 | 15
3 | 9


SecondTable:



PaymentKey      |      ImportantValue
1 | 2
2 | 5
3 | 21


I cannot modify the schema of PaymentHistory table, but I could alter the temporary table or the SecondTable if needed



I tried using OUTPUT to get both the identity and the ImportantValue, but since the ImportantValue is on the source table, I cannot get it with OUTPUT. I can't think of another way to link the data correctly, any help will be much appreciated





This question already has an answer here:




  • Is it possible to for SQL Output clause to return a column not being inserted?

    2 answers








sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 20:49

























asked Nov 20 at 20:29









Santiago San Martin

599




599




marked as duplicate by Damien_The_Unbeliever sql-server
Users with the  sql-server badge can single-handedly close sql-server questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 21 at 14:42


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Damien_The_Unbeliever sql-server
Users with the  sql-server badge can single-handedly close sql-server questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 21 at 14:42


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • Sample data and expected results might explain what you're after here.
    – Larnu
    Nov 20 at 20:35












  • Alright, I'll add some sample data, thanks
    – Santiago San Martin
    Nov 20 at 20:36


















  • Sample data and expected results might explain what you're after here.
    – Larnu
    Nov 20 at 20:35












  • Alright, I'll add some sample data, thanks
    – Santiago San Martin
    Nov 20 at 20:36
















Sample data and expected results might explain what you're after here.
– Larnu
Nov 20 at 20:35






Sample data and expected results might explain what you're after here.
– Larnu
Nov 20 at 20:35














Alright, I'll add some sample data, thanks
– Santiago San Martin
Nov 20 at 20:36




Alright, I'll add some sample data, thanks
– Santiago San Martin
Nov 20 at 20:36












2 Answers
2






active

oldest

votes


















1














I would add a column to your #PaymentHistory before the insert... and find out what the next val would be for the first table



alter table #PaymentHistory
add ID bigint identity(1,1)

declare @i bigint = (select max(PaymentKey) from PaymentHistory)


Now do your insert, ordered...



insert into PaymentHistory
select amount
from #PaymentHistory
order by ID


And insert into the second table



insert into SecondTable
select PaymentKey, ImportantValue
from PaymentHistory
inner join #PaymentHistory on #PaymentHistory.ID + @i = PaymentHistory.PaymentKey





share|improve this answer





















  • Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
    – Santiago San Martin
    Nov 20 at 20:43






  • 2




    MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
    – Jeroen Mostert
    Nov 20 at 20:43








  • 1




    I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
    – scsimon
    Nov 20 at 20:44








  • 1




    BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
    – Jeroen Mostert
    Nov 20 at 20:45










  • I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
    – scsimon
    Nov 20 at 20:46



















0














Alright, so it turns out someone from my team helped me come to an answer regarding this, I'm posting it here in case anyone stumbles upon this question



merge  PaymentHistory
using #PaymentHistory src
on 1 = 0
when not matched then
insert (amount) values (amount)
output inserted.PaymentKey, src.ImportantValue
into SecondTable (PaymentKey, ImportantValue)
;





share|improve this answer






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I would add a column to your #PaymentHistory before the insert... and find out what the next val would be for the first table



    alter table #PaymentHistory
    add ID bigint identity(1,1)

    declare @i bigint = (select max(PaymentKey) from PaymentHistory)


    Now do your insert, ordered...



    insert into PaymentHistory
    select amount
    from #PaymentHistory
    order by ID


    And insert into the second table



    insert into SecondTable
    select PaymentKey, ImportantValue
    from PaymentHistory
    inner join #PaymentHistory on #PaymentHistory.ID + @i = PaymentHistory.PaymentKey





    share|improve this answer





















    • Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
      – Santiago San Martin
      Nov 20 at 20:43






    • 2




      MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
      – Jeroen Mostert
      Nov 20 at 20:43








    • 1




      I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
      – scsimon
      Nov 20 at 20:44








    • 1




      BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
      – Jeroen Mostert
      Nov 20 at 20:45










    • I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
      – scsimon
      Nov 20 at 20:46
















    1














    I would add a column to your #PaymentHistory before the insert... and find out what the next val would be for the first table



    alter table #PaymentHistory
    add ID bigint identity(1,1)

    declare @i bigint = (select max(PaymentKey) from PaymentHistory)


    Now do your insert, ordered...



    insert into PaymentHistory
    select amount
    from #PaymentHistory
    order by ID


    And insert into the second table



    insert into SecondTable
    select PaymentKey, ImportantValue
    from PaymentHistory
    inner join #PaymentHistory on #PaymentHistory.ID + @i = PaymentHistory.PaymentKey





    share|improve this answer





















    • Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
      – Santiago San Martin
      Nov 20 at 20:43






    • 2




      MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
      – Jeroen Mostert
      Nov 20 at 20:43








    • 1




      I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
      – scsimon
      Nov 20 at 20:44








    • 1




      BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
      – Jeroen Mostert
      Nov 20 at 20:45










    • I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
      – scsimon
      Nov 20 at 20:46














    1












    1








    1






    I would add a column to your #PaymentHistory before the insert... and find out what the next val would be for the first table



    alter table #PaymentHistory
    add ID bigint identity(1,1)

    declare @i bigint = (select max(PaymentKey) from PaymentHistory)


    Now do your insert, ordered...



    insert into PaymentHistory
    select amount
    from #PaymentHistory
    order by ID


    And insert into the second table



    insert into SecondTable
    select PaymentKey, ImportantValue
    from PaymentHistory
    inner join #PaymentHistory on #PaymentHistory.ID + @i = PaymentHistory.PaymentKey





    share|improve this answer












    I would add a column to your #PaymentHistory before the insert... and find out what the next val would be for the first table



    alter table #PaymentHistory
    add ID bigint identity(1,1)

    declare @i bigint = (select max(PaymentKey) from PaymentHistory)


    Now do your insert, ordered...



    insert into PaymentHistory
    select amount
    from #PaymentHistory
    order by ID


    And insert into the second table



    insert into SecondTable
    select PaymentKey, ImportantValue
    from PaymentHistory
    inner join #PaymentHistory on #PaymentHistory.ID + @i = PaymentHistory.PaymentKey






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 20 at 20:39









    scsimon

    20.5k41536




    20.5k41536












    • Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
      – Santiago San Martin
      Nov 20 at 20:43






    • 2




      MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
      – Jeroen Mostert
      Nov 20 at 20:43








    • 1




      I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
      – scsimon
      Nov 20 at 20:44








    • 1




      BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
      – Jeroen Mostert
      Nov 20 at 20:45










    • I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
      – scsimon
      Nov 20 at 20:46


















    • Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
      – Santiago San Martin
      Nov 20 at 20:43






    • 2




      MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
      – Jeroen Mostert
      Nov 20 at 20:43








    • 1




      I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
      – scsimon
      Nov 20 at 20:44








    • 1




      BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
      – Jeroen Mostert
      Nov 20 at 20:45










    • I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
      – scsimon
      Nov 20 at 20:46
















    Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
    – Santiago San Martin
    Nov 20 at 20:43




    Feels a bit like a hack, but it's a lot better than what I was coming up with!! If there is no better answer tomorrow morning, I'll accept it with the green tick
    – Santiago San Martin
    Nov 20 at 20:43




    2




    2




    MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
    – Jeroen Mostert
    Nov 20 at 20:43






    MAX(Column) is not necessarily the next identity value for the column (and worse, it's NULL if the table is empty); that's IDENT_CURRENT('Table'). Even then all of this needs to be wrapped in a transaction to have any hope of correctness in the face of concurrency.
    – Jeroen Mostert
    Nov 20 at 20:43






    1




    1




    I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
    – scsimon
    Nov 20 at 20:44






    I didn't expect NULL which would break if it was a new table for sure. In that case, this wouldn't even be a problem. Why wouldn't it be the next (+1) based on the identity increment @JeroenMostert? Even if rows were deleted. Fair point on the transactions, but I'd do a lot of error handling too that i didn't include here.
    – scsimon
    Nov 20 at 20:44






    1




    1




    BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
    – Jeroen Mostert
    Nov 20 at 20:45




    BEGIN TRANSACTION; INSERT ...; ROLLBACK. Voila, now your identity is higher than the max ID present.
    – Jeroen Mostert
    Nov 20 at 20:45












    I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
    – scsimon
    Nov 20 at 20:46




    I see, and assumed they'd set xact_abort on so one insert couldn't happen if the other failed (was rolled back)
    – scsimon
    Nov 20 at 20:46













    0














    Alright, so it turns out someone from my team helped me come to an answer regarding this, I'm posting it here in case anyone stumbles upon this question



    merge  PaymentHistory
    using #PaymentHistory src
    on 1 = 0
    when not matched then
    insert (amount) values (amount)
    output inserted.PaymentKey, src.ImportantValue
    into SecondTable (PaymentKey, ImportantValue)
    ;





    share|improve this answer




























      0














      Alright, so it turns out someone from my team helped me come to an answer regarding this, I'm posting it here in case anyone stumbles upon this question



      merge  PaymentHistory
      using #PaymentHistory src
      on 1 = 0
      when not matched then
      insert (amount) values (amount)
      output inserted.PaymentKey, src.ImportantValue
      into SecondTable (PaymentKey, ImportantValue)
      ;





      share|improve this answer


























        0












        0








        0






        Alright, so it turns out someone from my team helped me come to an answer regarding this, I'm posting it here in case anyone stumbles upon this question



        merge  PaymentHistory
        using #PaymentHistory src
        on 1 = 0
        when not matched then
        insert (amount) values (amount)
        output inserted.PaymentKey, src.ImportantValue
        into SecondTable (PaymentKey, ImportantValue)
        ;





        share|improve this answer














        Alright, so it turns out someone from my team helped me come to an answer regarding this, I'm posting it here in case anyone stumbles upon this question



        merge  PaymentHistory
        using #PaymentHistory src
        on 1 = 0
        when not matched then
        insert (amount) values (amount)
        output inserted.PaymentKey, src.ImportantValue
        into SecondTable (PaymentKey, ImportantValue)
        ;






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 at 13:29

























        answered Nov 21 at 13:08









        Santiago San Martin

        599




        599















            Popular posts from this blog

            Tonle Sap (See)

            I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

            Guatemaltekische Davis-Cup-Mannschaft