Transactional Replication on SQL Server 2005 Enterprise x64 (SP3).
I need to add check constraints to a databases that is the target for a replication, but I cannot add the check constraints to the publishing database. The Problem is that the replication process keeps removing my constraints. How do I prevent this?
You could create some ddl triggers to prevent the constraint being removed. however replication would fail horribly if you alowed the publishing database to publish data that violated the constraint, which is a distinct posibility if you cannot add the constraint to the master database.
Related
Initial question (solution comes afterwards):
I have the following challenge: I have an Oracle database where a software (Infor Supplier Exchange) once created tables and filled them with data. This db shall be migrated to SQL Server, then an upgrade of the Infor software shall be executed with the migrated data.
A colleague of mine already used a script by Microsoft to migrated the Oracle db to SQL Server which is now available for me. Even though the "Keep Identity" flag was set, no primary key in the new db has its Identiy (autoincrement) set - but that is needed by the Infor software to add data later.
I found a way via SSMS to change the Identity (as well as its seed) for each relevant db table: Right-click on the table, design, change the "Identity Specification" manually. But I have over 300 tables: The effort would cost hours (and sanity).
I also found out that I can use SSMS's "export data" task. You have to know that the Infor software provides a db installer which creates all necessary tables, keys, identity properties, etc. with an EMPTY database. So I can basically export the data from the "Oracle migrated old db" to the "Infor prepared new db" since they (should) have the same table names, keys etc. - except the Identity property and the user data.
In the export data task you can check "Enable identity insert". The problem is that this SSMS feature aborts when it processes a table with foreign keys where the referenced table does not exist, yet. So I could go through the old db again, execute the "copy data" task for all tables without primary keys first, then try the remaining tables until all data is copied to the new db. But this is again much effort since I have to go back on every error or check all contraints beforehand.
Do you have a better approach? Is it possible to copy data from db A (with 300+ tables) to db B (with the same table structure), hoping that a tool solves the correct order of tables because of their foreign key constraints?
If you have questions on the issue I can explain in more detail. Thanks in advance.
Solution:
I solved the task by disabling constraints and triggers temporarily. The steps are:
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
EXEC sp_MSForEachTable "DELETE FROM ?"
I had to clear the target database's tables since they are filled with some sample data by the Infor installer. The data export task can append rows or can try to remove existing rows (with same primary keys). But this uses TRUNCATE internally which doesn't work with foreign key contraints, even when they are disabled by the above command.
Next: Execute the SSMS database task "Export data". Ignore datatype conversion errors (some types differ from Oracle-Migration to target SQL schema, like varchar to nvarchar which I checked and judged as not critical).
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
sp_msforeachtable #command1="print '?'", #command2="ALTER TABLE ? ENABLE TRIGGER all"
Using the vendor's SQL Server database schema and loading the data yourself is typically the correct approach for migrating to SQL Server with packaged software. But there may be additional guidance available from the vendor.
Instead of trying to load the tables in an order that is compatible the foreign key constraints, which is not always even possible, disable all the foreign keys before loading the database and re-enable them after. See eg Temporarily disable all foreign key constraints
SQL Server 2012, 2014, 2016 transactional replication
Publication is created. (copy Foreign Keys is false, the default)
Subscription is created.
Snapshot and sync.
Turn off synchronization.
Upgrade the publication database.
Upgrade the subscriber database for tables affected by modified views.
Set the snapshot to only gather information for changes.
Restart sync.
There is now an error at the subscriber because the two new columns exist and the snapshot is trying to create them but with foreign keys.
Typically it hasn't cared but now it seems to because of the FK creation it wants to do. If I manually delete the two new columns the sync will now create them again but with FKs.
The same operation happens for other new fields but we've never run into this issue before.
Looking to understand why FKs are being sent and if there is a workaround or setting.
I don't have much experience on SQL replication(SQL Server 2014). My client have a replication process which was created by his previous contractor. It worked well and suddenly it stopped replicating DDL statements couple of days ago. We have not done any change related to replication. When I checked data, subscriber has received up to date data. Only DDL statements have the problem. It uses transactional replication.
When I searched on web it says that the "Replicate schema changes" option need to set as true on Publication Properties.In my case it was already set to true.
Is there anyway for me to fix this and again have DDL statements to replicate as earlier?
Thank you
SQL Server Replication does support schema changes, but not all of them. In your case, CREATE PROCEDURE is not a supported schema change. Why? It's not an article yet, and not marked for replication, thus it cannot be replicated - replication has no way of knowing whether or not you would want that object replicated.
However, if you create the stored proc, then create an article for it, then issue an ALTER PROCEDURE, you will see the change replicated.
Please see article Make Schema Changes on Publication Databases:
Replication supports a wide range of schema changes to published objects. When you make any of the following schema changes on the appropriate published object at a Microsoft SQL Server Publisher, that change is propagated by default to all SQL Server Subscribers:
ALTER TABLE
ALTER TABLE SET LOCK ESCALATION should not be used if schema change replication is enabled and a topology includes SQL Server 2005 or SQL Server Compact 3.5 Subscribers.
ALTER VIEW
ALTER PROCEDURE
ALTER FUNCTION
ALTER TRIGGER
ALTER TRIGGER can be used only for data manipulation language [DML] triggers because data definition language [DDL] triggers cannot be replicated.
Please ensure you read the whole article, to be fully aware of what can be replicated, and under what circumstances.
I currently have SQL Server Transactional replication running. Server A (Publisher & Distributor) to Server B (Subscriber). Everything is working great. I just need to know whether i can add a table to the subscriber only in that database? will it affect my replication? must the databases be the exact same in terms of schema etc?
I need to add a table that's not part of the publishers published articles on Server B(Subscriber).
I just need to know whether i can add a table to the subscriber only
in that database?
Yes, you can. It won't affect to the replication, but, for example, if you create table dbo.A on subscriber database first and later you'll create table with the same name and schema on publisher database you can lost data in table dbo.A on subscriber because by default new articles on the subscriber will be drop if exists within initialize process.
You can change this behavior in publication properties.
must the databases be the exact same in terms of schema etc?
No, it must not. In transaction replication you can replicate either whole tables or some columns of those tables.
I'm working on the old C++ MFC project (> 10 years old). Database application works with migrating from MS Access (2007) to MS SQL Server (2008 R2) and I faced some hurdles on the way. For exporting data I used MS SQL Management Studio ("Import" option in the menu)
As it's known, there are some differences in data types between Access and MS SQL. That turned into some troubles.
Columns "ID" from Access (Autonumber, not NULL, primary keys) become just usual columns in SQL Server (int, not NULL and without any autoincrement). So I got lots of mistakes while inserting new rows into the tables.
Yes/No type in Access (-1/0; NULL is not allowed) becomes bit (1/0/NULL), logic of work shouldn't be broken as in the most of the places it is comparision of being not equal to 0:
query.Select()
.Buff("ID", &code)
.FromS("%Table_Name%", NULL)
.Where().Str("Aktiv <> 0")
.Execute();
Looking for a solution I saw the advice to use SSMA (SQL Server Migration Assistant) for Access. It's much better and more intellectual as it recreated primary/foreign keys, created CHECK's, indexes. But unfortunately lots of the FOREIGN KEYs' action Update/Delete operation become not Cascade but No Action. Warning message after schema import:
FOREIGN KEY constraint "Reference77" on MS Access table %Table1% may cause circular or multiple cascade paths. The cascade option from table %Table2% to table %Table1% was set to No option in SQL Server.
And that's not a surprise application gets some errors while deleting objects, though it was all OK in Access. For testing I selected one delete operation (in application) which got errors. I watched error messages and changed No Action -> Cascade for the involved FOREIGN KEYS via SSMS (SQL Server Management Studio). After that delete operation in the application succeeded.
My questions are:
Am I right I need only to change No Action -> Cascade for the FOREIGN KEYs to get the database application can work completely proper? Or there can appear another issues I don't know?
How can it be realized? I would like it to be a good solution for applying it on clients' SQL Servers.
Thanks for help, I really appreciate it!
Thanks for your answer. The solution for my problem is ... exporting data directly from Access (2010) to SQL Server.
I tried:
"SQL Server Import and Export Data", result - copying of only data from Access database, no any primary oк foreign keys, no transformation of autonumber to a column with IDENTITY and autoincrement.
SQL Server Migration Assistant for Access, result - a lot of foreign keys lost CASCADE property for update/delete operations. But all another things are OK.
Access 2010! Database Tools -> SQL Server -> ... using wizard -> all is OK with schema and data. Application works fine with the SQL Server database imported from Access.
So direct export from Access to SQL Server gave the required result.
Probably, but you will still need to test.
For a reusable solution, I would script the database that SSMA created (checking that all the types and foreign keys are correct). Having this script you can create an empty SQL Server database on any number of servers.
To populate these databases I'd use an Integration Services package. It's very easy to create by using Import wizard: going thru all the steps, but saving the package instead of running it immediately. Then you can open this package and edit it (adding data conversions or any other logic if necessary).