Why does merge replication fail on setting a table's LOCK_ESCALATION? - sql-server

We're having a problem with a merge replication. Our publisher runs SQL Server 2008, while our two subscribers run 2005. Our publisher is trying to send an ALTER TABLE Foo SET (LOCK_ESCALATION) command out to our subscribers. I think I remember reading that this command is new in SQL Server 2008, and if so, it makes sense that the command would fail on our 2005 servers. Our merge replication is set up for 2005 compatibility, however.
The schema script 'if object_id(N'[dbo].[Users]') is not null exec('ALTER TABLE [dbo].[Users] SET (LOCK_ESCALATION = TABLE)
')' could not be propagated to the subscriber.
Any ideas on why our publisher would be trying to do this?
Edit: Our 2008 server's compatibility level is set to "Sql Server 2005 (90)"

Its a new feature in sql 2008 so not supported in 2005. Depending on how complex your setup is you may want to consider have your database run in compatibility 90 (sql 2005) to make sure you dont add sql 2008 features to your database. Have had big issues with replication of schema data ever since it came about so always a bit reticent. I always try and make it act dumb and just manage data - had to support a merge system with 32 subscribers with merge replication and had big schema issues constantly when we pushed schema changes.
That said if it works as documented it shouldn't be trying to push your lock change. Check the subscriptions are marked as sql 2005 compatible. Its likely they haven't created an auto map of the setting from 2008 to 2005 in the way they did for data types (for example)
One of the SQL dev guys blogged on the new locking types a while back

This occurs because the incompatibility of this instruction with sql server 2005 and aparently when I do a schema change in a table that is replicating puts this instruction in the schema changes.
There are two ways: Remove and create again the suscription, not applicable when It's in production server. Second way is go to sysmergeschemachange table in the database and delete the row that has something like this:
The schema script 'if
object_id(N'[dbo].[Users]') is not
null exec('ALTER TABLE [dbo].[Users]
SET (LOCK_ESCALATION = TABLE) ')'
could not be propagated to the
subscriber.
I hope this helps.

Related

Table sysobjects has changed or does not longer exist after SQL Server 2005. What is the equivalent?

I am looking at a report for upgrade compatability on sql server and seeing the following error:
Table sysobjects has changed or does not longer exist after SQL Server 2005. Using it may cause errors. For more details, please see: Line X, Column Y.
We are moving to SQL server 2016 what would I need to replace sysobjects with.
The portion of the stored proc that is generating the above 110 compatibility message looks as follows:
SELECT name FROM sysobjects
Many of the system tables from earlier releases of SQL Server are now
implemented as a set of views. These views are known as compatibility
views, and they are meant for backward compatibility only. The
compatibility views expose the same metadata that was available in SQL
Server 2000. However, the compatibility views do not expose any of the
metadata related to features that are introduced in SQL Server 2005
and later.
Here you can find the list of System Compatibility Views
Besides, if you search in google for sysobject/other "old" system table, the first thing that will be written there is that the table is deprecated, use new_ system_view instead, this way you can find the new one

Collation change on MS sql server 2012

Dear all, Currently I am just researching how I could handle the change of the collation on the database.
Somebody made an unusual decision to create accent sensitive database for global use... but I am on the way to handle this!
REASON: of changing the collation is that database contains data collected from different countries and as we all know some of cultures have their own letters.
With the respect for the customers, our organization would like to have Accent Insensitive database. That will allow users to request data from the server without any limitations using local characters.
As far as I have find out, there may be an option to drop constraints and etc. change collation and then just to bring everything back. In this case I am afraid if this would be enough to affect already existing data (columns).
Another way, I have found an article in Collation change on 2005 and 2008 server. However, this does not include the 2012 server.
Also I am taking the complexity of this example into consideration as well.
I believe that I am not in an easy phase. But I am hoping to get few advises what would be the best and safest way to handle this.
Thank you for your concerns and assistance.
UPDATE let me add what architecture do we have: The complete system contains 4 databases and more than 1.000 tables in total. So my expectations is that not all of the possible ways may work in an optimal way.
me too i had to deal with a similar issue because of a different reason: ancient databases with an old SQL collation installed ages ago on a SQL6.5 server that has been inplace upgraded for each version from sql 7 to sql 2005 and now should be updated to sql 2012.
why all these inplace upgrades? because the actual collation was the server collation and was so old that is not available during then install process of a recent version (2000+) of sql server...
i decided to drop all that old rubbish so i had to find a way that allowed me to move to a new installation with a windows collation.
i had to exclude the data migration (create a new database and import data) because of the lack of documentation and the huge number of customizations, triggers, hidden rules and so on.
the solution i used (the order matters):
disable automatic statistics generation
script the creation of all foreign keys and then drop them
script unique and primary indexes and then drop them
script all remaining indexes and then drop them
script custom statistics and then drop them
script CHECK and DEFAULT constraints and then drop them
now you can run the ALTER commands needed to change the collation of the columns and change the collation of the database itself.
when done repeat the above in reverse order to rebuild all the needed objects.
it happens that if the database is so old as is mine you may incur in something funny like existing foreign key that references fields with different datatypes.
Changing collation of all existing columns is a real pain. I suggest a side-by-side migration rather than alter each column individually. Create a new database with the desired collation containing only empty tables. Copy data from the old db to the new one using INSERT...SELECT (or the ETL tool of your choice), and then create constraints, indexes, and other database objects.
Consider upvoting the Make it easy to change collation on a database SQL Server feature request.
There are a number of complicated solutions on the internet for inplace collation changes but the simplest (and safest) way we have found is to script out the database, alter the script to create a new db with the collation set at the start and then import the data to the new database.
We achieve this using MS SQL Server 2012 Management Studio in the following way:
Script out all database objects with Tasks -> Generate Scripts -> Script entire Database and all Database objects
Alter the script with the following 2 changes and then run it to create a new database:
a) Change DB name to MY-NEW-DB
b) Under the CREATE DATABASE statement add: ALTER DATABASE [MY-NEW-DB] collate Latin1_General_CS_AS
If desired, use a tool like RG SQL Compare to compare the old and new database to verify all indexes, constraints, types etc were the same and collation on relevant columns only was changed.
Run Tasks->Import Data ensuring 'Enable Identity Insert' checked. All data transferred to the new case sensitive database correctly.
Run DBCC CHECKDB if you wish to check consistency

DDL Statements does not replicated on SQL

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.

Database availability during database update

I have a database from a 3rd party. They supply a tool to update the database data weekly. The tool is pretty old and uses ODBC. Updates can either be incremental or can delete all database data then recreate the data. The update can take several hours. In order to have high availability, it was suggested to have 2 SQL databases, and store a "active database" setting in another database to determine which of the two databases applications should use (while the other could be being updated).
One issue we are running into is: How to do reference the active database in stored procedures in other databases?
Is this the right approach? Is there a simple, perhaps-infrastructure-based approach? (Should this be posted on ServerFault?)
Note: Databases are read-only besides the update tool.
If the databases are on different servers, you can create an alias for the server which will redirect to the other server in SQL Server Configuration Manager. Under SQLNative Client 10.0 Configuration (or 9.0 if you're in SQL Server 2005) you can add a new alias.
Otherwise, you can always rename the databases using sp_dbrename so thata your client applications are always using database1 while you are updating database2.
If you want to use different databases inside a stored procedure you either need to:
Duplicate all the calls. Ugly. You would end with a lot of:
if #firstDatabase=1
select * from database1..ExampleTable where ...
else
select * from database2..ExampleTable where ...
Use dynamic queries. Less ugly:
set #sqlQuery='select * from '+#currentDatabase+'..ExampleTable where...'
exec sp_executesql #sqlQuery
I admit that neither solution is perfect...
I'd take the approach of having the stored procedures in both databases with some sort of automatic trigger to update the stored procedures in the other database if a stored procedure is changed.

Is there an elegant way to track the modification of all columns of one table in SQL Server 2008

There is a table in my database containing 100 columns. I want to create a trigger to audit the modification for every update operation.
What I can think is to create the update clause for all columns but they are all similar scripts. So is there any elegant way to do that?
Check Change Data Capture
Update
CDC provides tracking of all details of changes. Available since SQL Server 2008.
(Change data capture is available only on the Enterprise, Developer, and Evaluation editions of SQL Server.
Source: http://msdn.microsoft.com/en-us/library/bb522489.aspx)
More lightweight solution is Change Tracking (Sync Framework), the one code4life mentioned before, available since SQL Server 2005.
Update2:
Related questions (with a lot of sublinks):
History tables pros, cons and gotchas - using triggers, sproc or at application level
History tables pros, cons and gotchas - using triggers, sproc or at application level
Suggestions for implementing audit tables in SQL Server?
Suggestions for implementing audit tables in SQL Server?
Are soft deletes a good idea?
Are soft deletes a good idea?
How do I version my MS SQL database in SVN?
Versioning SQL Server database
Thomas LaRock. SQL Server Audit: Magic without a Wizard
http://www.simple-talk.com/sql/database-administration/sql-server-audit-magic-without-a-wizard/
There's this resource on MSDN which you might find helpful:
Tracking Changes in the Server Database (including SQL Server 2008)
I'm not sure if you're using SQL Server 2008 though.
Code generation?
Have you looked at the techniques which http://autoaudit.codeplex.com/ uses?
Theoretically, you can use 1 trigger and check COLUMNS_UPDATED() to know which columns has changed.
(not be tested)
See more here

Resources