Change Not For Replication Value for SQL Server Identity Columns

(https://www.mssqltips.com/sqlservertip/1274/change-not-for-replication-value-for-sql-server-identity-columns/)


Problem
When setting up replication there are many things to think about and many options you can choose from when setting up your publications and subscriptions.  In most cases replication is an after thought and not part of the original database or application design, so there may be some required changes that need to be done when replication is setup.  The most important part is that the table has a primary key.  All tables should have a primary key when they are created, but sometimes this is not addressed and for replication to work this needs to be setup.  In addition, if you are using merge replication you need to have a RowGuid column.  Also, if you use identity columns you need to make sure the not for replication parameter is turned on. 

Luckily when setting up replication SQL Server will handle the RowGuid and the not for replication settings for your identity columns. but the primary key issue is something you still need to address manually.  Although it is great that SQL Server handles the not for replication setting for you, what is the process to turn this off or turn this on for tables? 

Solution
The "Not For Replication" setting for identity columns allows replication to pass the ID value from the publisher to the subscriber without the subscriber creating a new ID.  Since identity columns will always generate a new number when records are inserted, this setting allows you to ensure the values on both your publisher and subscribers stay in synch.

For SQL Server 2005 this option can be set when designing or creating a new table as shown below in the highlighted section.

For SQL Server 2000 this option can be set when designing or creating a new table as shown below in the highlighted section.

To create a table with the not for replication syntax using a script you would do something as follows:

CREATE TABLE [dbo].[Table_1](
[ProductID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[ProductName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[ProductDescription] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED

As mentioned above replication is not always thought about when tables are first created and therefore this "Not For Replication" option is not usually set to YES.  Also, I mentioned that when replication is setup these options are changed for you by the replication setup process.  But if you remove replication this setting stays as yes or if you need to keep a development schema (which is not replicated) in synch with your production schema (which is replicated) how can you do this without having to manually change each table via the table designer?

SQL Server 2005
In SQL Server 2005 a new system stored procedure has been created to allow you to turn on or turn off this "Not For Replication" setting.  This new stored procedure is sys.sp_identitycolumnforreplication.  Following is the code of this new SP.  As you can see it makes a call to a some process %%ColumnEx which is a bit cryptic.

SET ANSI_NULLS ON 
SET 
QUOTED_IDENTIFIER ON 
GO 

-- 
-- Name: 
--  sp_identitycolumnforreplication 
-- 
-- Description: 
--   This procedure allows customers to set the NFR on 
-- identity columns for a particular table. 
-- 
-- Returns: 
--   0-Success 1-Failure 
-- 
-- Security: DBO check 
-- 
-- Requires Certificate signature for catalog access 
-- 
CREATE PROCEDURE [sys].[sp_identitycolumnforreplication] 

   
@object_id  INT
   
@value      bit 

AS 
BEGIN 
   DECLARE 
@identity_column sysname 

   
IF IS_SRVROLEMEMBER('sysadmin'
       
AND IS_MEMBER('db_owner'
   
BEGIN 
       RAISERROR
(2105014, -1
       
RETURN 
   
END 

   SELECT 
@identity_column NULL 

   
SELECT @identity_column name  
       
FROM sys.columns 
       
WHERE OBJECT_ID @object_id 
           
AND COLUMNPROPERTY(OBJECT_IDname'IsIdentity'
   
IF @identity_column IS NOT NULL 
   
BEGIN 
       EXEC 
%%ColumnEx(ObjectID @object_idName @identity_column).SetIdentityNotForRepl(Value @value
       
IF @@ERROR <> 0  
           
RETURN 
   
END 

   RETURN 

END

By using this new SP along with the sp_msforeachtable which iterates through all tables you can turn this on for all tables or off for all tables as follows:

This script turns it YES for all tables that have an identity column.

EXEC sp_msforeachtable @command1 = '
declare @int int
set @int =object_id("?")
EXEC sys.sp_identitycolumnforreplication @int, 1'

This script turns it NO for all tables that have an identity column.

EXEC sp_msforeachtable @command1 = '
declare @int int
set @int =object_id("?")
EXEC sys.sp_identitycolumnforreplication @int, 0'

 

SQL Server 2000
In SQL Server 2000 it is not quite as simple to make this change.  There is not a stored procedure like there is for SQL Server 2005.  The following code snippet will allow you to change this value across the board for all tables in a database as well, but this is updating the system table syscolumns directly.  Most of what you read will tell you not to update the system tables directly.

This script turns it YES for all tables that have an identity column.

xupdate syscolumns
set colstat = colstat | 0x0008 
where colstat & 0x0008 = 0 -- ie not already "not for replication" 
and colstat & 0x0001 <> 0 -- ie identity column

When trying to run this you may get the following error message.  You need to make this change in order to run these queries.

Server: Msg 259, Level 16, State 2, Line 1
Ad hoc updates to system catalogs are not enabled. The system administrator must reconfigure SQL Server to allow this.

Next Steps

  • If the need arises to turn on or turn off the not for replication setting now you now how to go about making the change
  • Keep in mind that when changing this value using the table designer, SQL Server creates a temporary table, drops the existing table and renames the new table.  This is not a simple update.
  • Be careful changing system tables.  A wrong update could be disastrous.  Make sure you have database backups prior to changing any system tables directly.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
If the Debezium Kafka Connect for SQL Server topic is missing, you can try the following steps: 1. First, check the configuration of the Kafka Connect source connector for SQL Server. You should ensure that the connector configuration includes the correct topic name for the Debezium SQL Server source connector. The topic name should be specified in the "topic.prefix" or "topic.name" configuration property, depending on the version of Debezium you are using. 2. If the topic name is specified correctly in the connector configuration, you can try restarting the Kafka Connect worker and the Debezium SQL Server source connector. This may help to resolve any issues that are preventing the topic from being created. 3. If the topic still does not exist after restarting the Kafka Connect worker and connector, you can try creating the topic manually using the Kafka command line tools. For example, you can use the following command to create a new topic with a replication factor of 1 and a partition count of 3: ``` bin/kafka-topics.sh --create --bootstrap-server <kafka_broker>:<kafka_port> --replication-factor 1 --partitions 3 --topic <topic_name> ``` Replace `<kafka_broker>` and `<kafka_port>` with the hostname and port of your Kafka broker, respectively, and `<topic_name>` with the name of the missing topic. 4. If none of the above steps work, you may need to investigate further to identify the root cause of the issue. You can check the Kafka Connect and Debezium logs for any error messages or warnings that may provide more information on the issue.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值