Force column order - Identity_Insert when no PK defined

LxocramLxocram Posts: 25 Bronze 3
edited March 8, 2012 11:34AM in SQL Compare Previous Versions
When i put option Force Column Order on I frequently get errors like

Msg 544, Level 16, State 1, Line 1
Cannot insert explicit value for identity column in table 'tmp_rg_xx_sec_dossierbeheerder_departement' when IDENTITY_INSERT is set to OFF.

The problem occurs when the table has no PK but it does have an identity column(wich is in fact a PK column)

The synchronization script is missing two statements

PRINT N'Rebuilding [dbo].[sec_dossierbeheerder_departement]'
GO
CREATE TABLE [dbo].[tmp_rg_xx_sec_dossierbeheerder_departement]
(
[ID_Link_Dossierbeheerder_Departement] [int] NOT NULL IDENTITY(1, 1),
[ID_departement] [tinyint] NULL,
[ID_Personeelslid_Dossierbeheerder] [int] NULL,
[geldig_van] [datetime] NOT NULL DEFAULT ('01/01/1900'),
[geldig_tot] [datetime] NOT NULL DEFAULT ('31/12/2999'),
[geldig] AS (case when [Geldig_Van]<dateadd(day,(0),datediff(day,(0),getdate())) AND [geldig_Tot]>=dateadd(day,(0),datediff(day,(0),getdate())) then (1) else (0) end),
[NTUsername] AS ([dbo].[get_Username_Personeelslid_COMPUTED_COLUMN]([ID_Personeelslid_Dossierbeheerder]))
)
GO
SET IDENTITY INSERT [dbo].[tmp_rg_xx_sec_dossierbeheerder_departement] ON
go
INSERT INTO [dbo].[tmp_rg_xx_sec_dossierbeheerder_departement]([ID_Link_Dossierbeheerder_Departement], [ID_departement], [ID_Personeelslid_Dossierbeheerder], [geldig_van], [geldig_tot]) SELECT [ID_Link_Dossierbeheerder_Departement], [ID_departement], [ID_Personeelslid_Dossierbeheerder], [geldig_van], [geldig_tot] FROM [dbo].[sec_dossierbeheerder_departement]
GO
SET IDENTITY INSERT [dbo].[tmp_rg_xx_sec_dossierbeheerder_departement] OFF

GO
DECLARE @idVal BIGINT
SELECT @idVal = IDENT_CURRENT(N'[dbo].[sec_dossierbeheerder_departement]')
IF @idVal IS NOT NULL
DBCC CHECKIDENT(N'[dbo].[tmp_rg_xx_sec_dossierbeheerder_departement]', RESEED, @idVal)
GO
DROP TABLE [dbo].[sec_dossierbeheerder_departement]

Comments

  • Thanks for your post.

    You're absolutely right about what it *should* be doing, but I'm not sure why it isn't in your case. I've tested it here with the same table structure, and it seems to add the identity insert statements correctly.

    There must be something in the table that's causing the identity property to be missed.

    Can you run the following query in SSMS and make sure that 128 is returned for status?
    SELECT name, status FROM syscolumns WHERE name = 'ID_Link_Dossierbeheerder_Departement'
    

    Can you let me know what is being changed when you sync sec_dossierbeheerder_departement?
    Chris
  • LxocramLxocram Posts: 25 Bronze 3
    Chris,
    128 is returned

    I've tried it again with an other table

    creation script (SSMS)
    CREATE TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;&#40;
    	&#91;ID&#93; &#91;int&#93; IDENTITY&#40;1,1&#41; NOT NULL,
    	&#91;ID_Opleiding&#93; &#91;int&#93; NOT NULL,
    	&#91;ID_Opleidingsvoorzitter&#93; &#91;int&#93; NOT NULL,
    	&#91;Geldig_Van&#93; &#91;datetime&#93; NOT NULL,
    	&#91;Geldig_Tot&#93; &#91;datetime&#93; NOT NULL,
    	&#91;GELDIG&#93;  AS &#40;case when &#91;Geldig_Van&#93;&lt;dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; AND &#91;geldig_Tot&#93;&gt;=dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; then &#40;1&#41; else &#40;0&#41; end&#41;,
    	&#91;ID_Departement&#93;  AS &#40;&#91;dbo&#93;.&#91;getID_Departement_From_ID_Opleiding_COMPUTED_COLUMN&#93;&#40;&#91;ID_Opleiding&#93;&#41;&#41;,
     CONSTRAINT &#91;PK__kzlst_Opleiding___17F5F1ED&#93; PRIMARY KEY CLUSTERED 
    &#40;
    	&#91;ID&#93; ASC
    &#41;WITH &#40;PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON&#41; ON &#91;PRIMARY&#93;
    &#41; ON &#91;PRIMARY&#93;
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; ADD  CONSTRAINT &#91;DF_kzlst_Opleiding_Voorzitter_Geldig_Van&#93;  DEFAULT &#40;'01/10/2009'&#41; FOR &#91;Geldig_Van&#93;
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; ADD  CONSTRAINT &#91;DF_kzlst_Opleiding_Voorzitter_Geldig_Tot&#93;  DEFAULT &#40;'31/12/2999'&#41; FOR &#91;Geldig_Tot&#93;
    GO
    

    SYNCRO SCRIPT (with ignore check constraints OFF and ignore identy increment OFF)
    SET NUMERIC_ROUNDABORT OFF
    GO
    SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS ON
    GO
    USE &#91;GPS&#93;
    GO
    PRINT N'Disabling DDL triggers'
    GO
    DISABLE TRIGGER ALL ON DATABASE
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;PK__kzlst_Opleiding___17F5F1ED&#93;
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;DF__kzlst_Opl__Geldi__60D0A58C&#93;
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;DF__kzlst_Opl__Geldi__61C4C9C5&#93;
    GO
    PRINT N'Rebuilding &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    CREATE TABLE &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;
    &#40;
    &#91;ID&#93; &#91;int&#93; NOT NULL IDENTITY&#40;1, 1&#41;,
    &#91;ID_Opleiding&#93; &#91;int&#93; NOT NULL,
    &#91;ID_Opleidingsvoorzitter&#93; &#91;int&#93; NOT NULL,
    &#91;Geldig_Van&#93; &#91;datetime&#93; NOT NULL DEFAULT &#40;'01/10/2009'&#41;,
    &#91;Geldig_Tot&#93; &#91;datetime&#93; NOT NULL DEFAULT &#40;'31/12/2999'&#41;,
    &#91;GELDIG&#93; AS &#40;case when &#91;Geldig_Van&#93;&lt;dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; AND &#91;geldig_Tot&#93;&gt;=dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; then &#40;1&#41; else &#40;0&#41; end&#41;,
    &#91;ID_Departement&#93; AS &#40;&#91;dbo&#93;.&#91;getID_Departement_From_ID_Opleiding_COMPUTED_COLUMN&#93;&#40;&#91;ID_Opleiding&#93;&#41;&#41;
    &#41;
    GO
    INSERT INTO &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;&#40;&#91;ID&#93;, &#91;ID_Opleiding&#93;, &#91;ID_Opleidingsvoorzitter&#93;, &#91;Geldig_Van&#93;, &#91;Geldig_Tot&#93;&#41; SELECT &#91;ID&#93;, &#91;ID_Opleiding&#93;, &#91;ID_Opleidingsvoorzitter&#93;, &#91;Geldig_Van&#93;, &#91;Geldig_Tot&#93; FROM &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;
    GO
    DECLARE @idVal BIGINT
    SELECT @idVal = IDENT_CURRENT&#40;N'&#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'&#41;
    IF @idVal IS NOT NULL
        DBCC CHECKIDENT&#40;N'&#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;', RESEED, @idVal&#41;
    GO
    DROP TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;
    GO
    EXEC sp_rename N'&#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;', N'kzlst_Opleiding_Voorzitter'
    GO
    PRINT N'Re-enabling DDL triggers'
    GO
    ENABLE TRIGGER trgNoRightJoins ON DATABASE
    GO
    

    :!: As you can see:
    * the constraints are not recreated under the same name (even if they were the same)
    * the primary key attribute is not recreated at all (even if it was there)

    Then I went back to the synchronisation option and found that ignore Identity property on columns was on

    SO if column on receiving end is allready an identity column and ignore identity property is ON the synchronisation fails

    Furthermore i changed 'ignore CONSTRAINT AND INDEX NAMES' to OFF
    SET NUMERIC_ROUNDABORT OFF
    GO
    SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS ON
    GO
    USE &#91;GPS&#93;
    GO
    PRINT N'Disabling DDL triggers'
    GO
    DISABLE TRIGGER ALL ON DATABASE
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;PK__kzlst_Opleiding___17F5F1ED&#93;
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;DF__kzlst_Opl__Geldi__60D0A58C&#93;
    GO
    PRINT N'Dropping constraints from &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    ALTER TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93; DROP CONSTRAINT &#91;DF__kzlst_Opl__Geldi__61C4C9C5&#93;
    GO
    PRINT N'Rebuilding &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'
    GO
    CREATE TABLE &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;
    &#40;
    &#91;ID&#93; &#91;int&#93; NOT NULL IDENTITY&#40;1, 1&#41;,
    &#91;ID_Opleiding&#93; &#91;int&#93; NOT NULL,
    &#91;ID_Opleidingsvoorzitter&#93; &#91;int&#93; NOT NULL,
    &#91;Geldig_Van&#93; &#91;datetime&#93; NOT NULL CONSTRAINT &#91;DF_kzlst_Opleiding_Voorzitter_Geldig_Van&#93; DEFAULT &#40;'01/10/2009'&#41;,
    &#91;Geldig_Tot&#93; &#91;datetime&#93; NOT NULL CONSTRAINT &#91;DF_kzlst_Opleiding_Voorzitter_Geldig_Tot&#93; DEFAULT &#40;'31/12/2999'&#41;,
    &#91;GELDIG&#93; AS &#40;case when &#91;Geldig_Van&#93;&lt;dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; AND &#91;geldig_Tot&#93;&gt;=dateadd&#40;day,&#40;0&#41;,datediff&#40;day,&#40;0&#41;,getdate&#40;&#41;&#41;&#41; then &#40;1&#41; else &#40;0&#41; end&#41;,
    &#91;ID_Departement&#93; AS &#40;&#91;dbo&#93;.&#91;getID_Departement_From_ID_Opleiding_COMPUTED_COLUMN&#93;&#40;&#91;ID_Opleiding&#93;&#41;&#41;
    &#41;
    GO
    SET IDENTITY_INSERT &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93; ON
    GO
    INSERT INTO &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;&#40;&#91;ID&#93;, &#91;ID_Opleiding&#93;, &#91;ID_Opleidingsvoorzitter&#93;, &#91;Geldig_Van&#93;, &#91;Geldig_Tot&#93;&#41; SELECT &#91;ID&#93;, &#91;ID_Opleiding&#93;, &#91;ID_Opleidingsvoorzitter&#93;, &#91;Geldig_Van&#93;, &#91;Geldig_Tot&#93; FROM &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;
    GO
    SET IDENTITY_INSERT &#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93; OFF
    GO
    DECLARE @idVal BIGINT
    SELECT @idVal = IDENT_CURRENT&#40;N'&#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;'&#41;
    IF @idVal IS NOT NULL
        DBCC CHECKIDENT&#40;N'&#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;', RESEED, @idVal&#41;
    GO
    DROP TABLE &#91;dbo&#93;.&#91;kzlst_Opleiding_Voorzitter&#93;
    GO
    EXEC sp_rename N'&#91;dbo&#93;.&#91;tmp_rg_xx_kzlst_Opleiding_Voorzitter&#93;', N'kzlst_Opleiding_Voorzitter'
    GO
    PRINT N'Re-enabling DDL triggers'
    GO
    ENABLE TRIGGER trgNoRightJoins ON DATABASE
    GO
    

    It is still missing the PK constraint

    So i put the option 'ignore indexes' OFF

    :!: I thought the ignore options where there to not detect a difference between tables, I did not know the full impact on the synchronisation script. If the table is synchronized for another reason (column order) and theres a table rebuild, it should not throw away constraints that were allready there (but ignored for tablediff)
  • LxocramLxocram Posts: 25 Bronze 3
    Chris,

    Do you get what i mean?
    Is use the ignore options to only detect some differences (my software is also uesd by another company so and some options are different like SQLUsers indexes etc... )

    But it seems that when a table rebuild occurs, the table is not fully rebuilt when some ignore options are on
  • Thanks for your reply, and sorry for the delay.

    I see what you mean, so I was just putting a test case together for the development team.

    I'll update you with a bug reference number.

    Sorry to not keep you updated.
    Chris
  • I've create the bug report now, so thanks for the poke.

    1) The identity Insert problem.

    I've confirmed this. If you use the 'ignore identity property' option and SQL Compare needs to rebuild the table. It forgets to set the identity insert when it inserts the data into the temp table. This is now logged under the bug tracking code SC-5647.

    2) Constraint Names

    It looks like the new constraint names are consistent with the names on the source schema, so I think this is the correct behaviour. The names are only ignored for the comparison, so a sync will always use the names from the source database.

    3) Recreation of PK.

    I couldn't reproduce this. The PK is actually recreated after the temp table is renamed to the correct table name, so it might just be happening further down the script to where you expect it, but it should be there.

    Does this explain the behaviour, or have I missed anything?
    Chris
Sign In or Register to comment.