Transactions 4

  • Ah yes, good point. I think that would have been a better way to put the question.

    John

  • John Mitchell-245523 (6/8/2012)


    IgorMi (6/8/2012)


    Try with XACT_ABORT = OFF and you'll see the same results as it is ON. In this case XACT_ABORT does not have impact of the inserted rows. However on the messages, yes it has.

    IgorMi

    True again, but you did not create a unique constraint, so there is nothing to fail. Therefore four rows are returned whether the setting is ON or OFF.

    John

    Hi

    I missed it intentionally. I just tried with IGNORE_DUP_KEY=OFF and the result is same.

    IgorMi

    Igor Micev,My blog: www.igormicev.com

  • John Mitchell-245523 (6/8/2012)


    IgorMi (6/8/2012)


    Try with XACT_ABORT = OFF and you'll see the same results as it is ON. In this case XACT_ABORT does not have impact of the inserted rows. However on the messages, yes it has.

    IgorMi

    True again, but you did not create a unique constraint, so there is nothing to fail. Therefore four rows are returned whether the setting is ON or OFF.

    John

    Hi

    I missed it intentionally. I just tried with IGNORE_DUP_KEY=OFF and the result is same.

    IgorMi

    Igor Micev,My blog: www.igormicev.com

  • IgorMi (6/8/2012)Hi

    I missed it intentionally. I just tried with IGNORE_DUP_KEY=OFF and the result is same.

    IgorMi

    Let's end the discussion once and for all 🙂

    The original question with ignore_dup_key=on:

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=on)

    go

    begin tran

    insert into qotd4(col1,col2,col3) values(1,'W','Some')

    insert into qotd4(col1,col2,col3) values(2,'Y','Some')

    insert into qotd4(col1,col2,col3) values(1,'X','Some')

    insert into qotd4(col1,col2,col3) values(3,'Z','Some')

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4Returns three rows: W,Y,Z

    The same statements, but this time with ignore_dup_key=off:

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=off)

    go

    begin tran

    insert into qotd4(col1,col2,col3) values(1,'W','Some')

    insert into qotd4(col1,col2,col3) values(2,'Y','Some')

    insert into qotd4(col1,col2,col3) values(1,'X','Some')

    insert into qotd4(col1,col2,col3) values(3,'Z','Some')

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4Returns three rows: W,Y,Z

    In addition, SQL server throws an exception, but this does not affect tha fact that three rows are returned.

    Msg 2601, Level 14, State 1, Line 4

    Cannot insert duplicate key row in object 'dbo.qotd4' with unique index 'q04_index'.

  • Nils Gustav Stråbø (6/8/2012)


    IgorMi (6/8/2012)Hi

    I missed it intentionally. I just tried with IGNORE_DUP_KEY=OFF and the result is same.

    IgorMi

    Let's end the discussion once and for all 🙂

    The original question with ignore_dup_key=on:

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=on)

    go

    begin tran

    insert into qotd4(col1,col2,col3) values(1,'W','Some')

    insert into qotd4(col1,col2,col3) values(2,'Y','Some')

    insert into qotd4(col1,col2,col3) values(1,'X','Some')

    insert into qotd4(col1,col2,col3) values(3,'Z','Some')

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4Returns three rows: W,Y,Z

    The same statements, but this time with ignore_dup_key=off:

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=off)

    go

    begin tran

    insert into qotd4(col1,col2,col3) values(1,'W','Some')

    insert into qotd4(col1,col2,col3) values(2,'Y','Some')

    insert into qotd4(col1,col2,col3) values(1,'X','Some')

    insert into qotd4(col1,col2,col3) values(3,'Z','Some')

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4Returns three rows: W,Y,Z

    In addition, SQL server throws an exception, but this does not affect tha fact that three rows are returned.

    Msg 2601, Level 14, State 1, Line 4

    Cannot insert duplicate key row in object 'dbo.qotd4' with unique index 'q04_index'.

    Hi,

    It is not possible the same result to be returned for IGNORE_DUP_KEY = ON and OFF. Are you missing something?

    When IGNORE_DUP_KEY = ON three rows are returned

    When IGNORE_DUP_KEY = OFF four rows are returned

    Here is my code for the both cases

    --1

    create table qotd4

    (

    col1 int,

    col2 char(1) not null,

    col3 varchar(20))

    create unique index q4_index on qotd4(col1) with (ignore_dup_key = on)

    Begin transaction

    insert into qotd4(col1,col2,col3) values(1,'w','some')

    insert into qotd4(col1,col2,col3) values(2,'y','or that')

    insert into qotd4(col1,col2,col3) values(1,'x','thing')

    insert into qotd4(col1,col2,col3) values(3,'z','or what')

    Commit transaction

    select col2 from qotd4 order by col2

    --2

    create table qotd5

    (

    col1 int,

    col2 char(1) not null,

    col3 varchar(20))

    create unique index q5_index on qotd4(col1) with (ignore_dup_key = off)

    delete from qotd5

    Begin transaction

    insert into qotd5(col1,col2,col3) values(1,'w','some')

    insert into qotd5(col1,col2,col3) values(2,'y','or that')

    insert into qotd5(col1,col2,col3) values(1,'x','thing')

    insert into qotd5(col1,col2,col3) values(3,'z','or what')

    Commit transaction

    select col2 from qotd5 order by col2

    The ouput 1:

    w

    y

    z

    The ouput 2:

    w

    x

    y

    z

    Regards

    IgorMi

    Igor Micev,My blog: www.igormicev.com

  • Your second table is qotd5, but you're still creating the unique index on qotd4--hence it's not too surprising you get all four results the second time, because there's no unique constraint on the qotd5 table!

  • Your second example creates and index on qotd4, not qotd5.

  • Nils Gustav Stråbø (6/8/2012)


    Your second example creates and index on qotd4, not qotd5.

    Oh!, Thanks

    Yes, you're right definitively.

    Thank you again

    IgorMi

    Igor Micev,My blog: www.igormicev.com

  • Guys,

    Just my $0.02. From BOL (http://http://msdn.microsoft.com/en-us/library/ms188783.aspx):

    IGNORE_DUP_KEY = { ON | OFF }

    Specifies the error response when an insert operation attempts to insert duplicate key values into a unique index. The IGNORE_DUP_KEY option applies only to insert operations after the index is created or rebuilt. The option has no effect when executing CREATE INDEX, ALTER INDEX, or UPDATE. The default is OFF.

    ON

    A warning message will occur when duplicate key values are inserted into a unique index. Only the rows violating the uniqueness constraint will fail.

    OFF

    An error message will occur when duplicate key values are inserted into a unique index. The entire INSERT operation will be rolled back.

    Note the last sentence. If you try the following code:

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=on)

    go

    begin tran

    insert into qotd4(col1,col2,col3)

    select 1,'W','Some' union

    select 2,'Y','Some' union

    select 1,'X','Some' union

    select 3,'Z','Some'

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4

    ----------------------------

    create table qotd4(col1 int not null, col2 char(1) not null, col3 varchar(20))

    create unique index q04_index on qotd4(col1) with (ignore_dup_key=off)

    go

    begin tran

    insert into qotd4(col1,col2,col3)

    select 1,'W','Some' union

    select 2,'Y','Some' union

    select 1,'X','Some' union

    select 3,'Z','Some'

    commit tran

    go

    select col2 from qotd4 order by col2

    go

    drop table qotd4

    Unlike the QOTD example that uses individual INSERTs for each row, here the second block of code fails to insert a row, while the first block still inserts 3 rows issuing a "Duplicate key was ignored." message.

    I hope this helps.

    "El" Jerry.

    "El" Jerry.

    "A watt of Ottawa" - Gerardo Galvan

    To better understand your help request, please follow these best practices.[/url]

  • IgorMi (6/8/2012)


    Nils Gustav Stråbø (6/8/2012)


    Thanks for the question.

    The result of the final SELECT statement would have been the same even if you had dropped the IGNORE_DUP_KEY=ON. The only difference is that it would have raised an error (Cannot insert duplicate key row...), but that wouldn't have aborted the transaction since XACT_ABORT is OFF (by default).

    So in my opinion the explanation is a little bit wrong. It is not the IGNORE_DUP_KEY that causes three rows to be returned, but the fact that a run time error does not cause the transaction (some do, but not a duplicate key error) to rollback as long as XACT_ABORT is OFF.

    Reference:

    http://msdn.microsoft.com/en-us/library/ms188792.aspx

    When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing. Depending upon the severity of the error, the entire transaction may be rolled back even when SET XACT_ABORT is OFF. OFF is the default setting.

    I don't agree with you.

    Ensured with a direct try.

    You can execute the following code and ensure yourself that the IGNORE_DUP_KEY = ON has done its effect.

    create table qotd5

    (

    col1 int,

    col2 char(1) not null,

    col3 varchar(20))

    set xact_abort on

    Begin transaction

    insert into qotd5(col1,col2,col3) values(1,'w','some')

    insert into qotd5(col1,col2,col3) values(2,'y','or that')

    insert into qotd5(col1,col2,col3) values(1,'x','thing')

    insert into qotd5(col1,col2,col3) values(3,'z','or what')

    Commit transaction

    select col2 from qotd5 order by col2

    Regards

    IgorMi

    You are missing the unique index on your table to actually test what John is saying. Hes point is: it doesnt matter if you turned IGNORE_DUP_KEY on you would get the same values inserted unless you set xact_abort on.

  • A nice one to finish my week. Thanks, Ron!

  • good question Ron - cheers.

    for me, i think that it is important to understand the difference between a warning and an error. If, for example, I use a TRY CATCH for error handling and have XACT_ABORT = OFF, then a warning would allow for the statement block to complete successfully, however, an error would result in the CATCH block determining how deal with the situation.

    happy Friday and bring on the weekend!

  • Can someone explain to me what purpose is served by ignoring duplicate keys?

    In an ideal world there would be data uniquely related to the key in such a way that a duplication of the key would imply a duplication of the remaining fields on the row related to that key - so ignoring a literally duplicated row might make sense.

    I don't know that I've ever seen that pattern in real life though. I imagine the duplicate key would likely have fields with different values than are already in the table. Silently discarding values offends my sense of "data integrity."

    Under what conditions is it acceptable to attempt an insert but not care whether it happens?

  • Good question.

    I haven't a clue which button I pressed, but in wasn't the one I thought I pressed. Finger trouble -> wrong answer.

    Tom

  • Mike Dougherty-384281 (6/8/2012)


    Can someone explain to me what purpose is served by ignoring duplicate keys?

    ...Under what conditions is it acceptable to attempt an insert but not care whether it happens?

    good question Mike - I'm curious to hear if anyone uses this in a production realm also. when it comes to data, I guess I am a control freak and i don't like the idea of blindly ignoring attempted inserts.

Viewing 15 posts - 16 through 30 (of 36 total)

You must be logged in to reply to this topic. Login to reply