VS SchemaCompare: Making Table Updates - sql-server

Does anyone know how the SchemaCompare in Visual Studio (using 2010 currently) determines how to handle [SQL Server 2008R2] database table updates (column data type, optionality, etc)?
The options are to:
Use separate ALTER TABLE statements
Create a new table, copy the old data into the new table, rename the old table before the new one can be renamed to assume the proper name
I'm asking because we have a situation involving a TIMESTAMP column (for optimistic locking). If SchemaCompare uses the new table approach, the TIMESTAMP column values will change & cause problems for anyone with the old TIMESTAMP values.

I believe Schema Compare employs the same CREATE-COPY-DROP-RENAME (CCDR) strategy as VSTSDB described here: link
Should be able to confirm this by running a compare and scripting out the deploy, no?

Related

SSDT does not publish column COLLATION change

It seems that SSDT does not publish column COLLATION, even though it detects a change during comparison process.
An issue appears that if you change a column COLLATION on a specific column in a table, and try to publish the change, the SSDT will ignore it when creating a publish script.
Here is a similar issue described on msdn forums, detected long ago, that is still reproduced.
I have been using SSDT version 14.0.60629.0
Does the SSDT still have this issue, or is there a valid workaround?
Update
This issue is only for the columns which are using a User-Defined Data Type.
Update
(added steps to reproduce, and corrected the question text):
Steps to reproduce:
1. Start with a database and note the collations(this is the one I have, a DB on my Dev server):
Current COLLATION setup is:
ServerSQL_Latin1_General_CP1_CI_AS
DatabaseSQL_Latin1_General_CP1_CI_AS
TableSQL_Latin1_General_CP1_CI_AS
User-Defined Data Type (dt_Source AS varchar(20))SQL_Latin1_General_CP1_CI_AS
Column (Source AS dt_source)SQL_Latin1_General_CP1_CI_AS
2.Then change the database collation.
USE master;
ALTER DATABASE [<db_name>] COLLATE SQL_Latin1_General_CP1250_CS_AS
New COLLATION setup will be:
ServerSQL_Latin1_General_CP1_CI_AS
DatabaseSQL_Latin1_General_CP1250_CS_AS
TableSQL_Latin1_General_CP1250_CS_AS
User-Defined Data Type (dt_Source AS varchar(20))SQL_Latin1_General_CP1250_CS_AS
Column (Source AS dt_source)SQL_Latin1_General_CP1_CI_AS
Previous column collation (SQL_Latin1_General_CP1_CI_AS) will remain, and SSDT Compare mechanism will not be able to detect any change.
This will lead to an error message, if I try to create a Foreign Key constraint on this column, referencing another, newly populated column, in another table, because the Publish Script from Comparison was built without knowing the true collation.
For, example, this produces an error, because column collations are different:
ALTER TABLE [FCT].[Inventory] WITH NOCHECK
ADD CONSTRAINT [FK_Inventory_Source] FOREIGN KEY ([Source]) REFERENCES [DIM].[Source] ([SourceCode]);
Make sure you ENABLE "script database collation" in the publish settings (tab: general)
source: https://dba.stackexchange.com/questions/128002/ssdt-publish-window-what-does-checkbox-enable-mean
then it might take multiple publications
first it does on db level, later on table/column level

SSIS no-match lookup? SQL server integration services - prevent duplicate rows

In ssis 2012, let's presume I simply copy customer data from one DB Source to a DB Destination (both are different database instances, one cannot "see" the other).
How do I prevent adding customer data I already added before. In other words, when I rerun the task, it should not add the customer twice or more (only the ones that previously failed). We have a non-unique reference available in the destination customer table e.g. 'SourceCustomerID' which is non-unique!
So we cannot rely on some unique index in the Destination table(s), and if we could, I don't want go this way (would cause failures)...
Added based on questions below: there ARE columns that uniquely identify data in the target table, and we need these for this, but these are nor implemented as unique indexes, nor do I want to let the job (or rows) fail like this. I want to prevent adding these rows in a controlled way.
I tried the lookup component, playing with "Lookup No Match Output", etc...no luck yet.
Any ideas how to accomplish this using the SSIS principles??
Best regards
Bart.
Use the SCD component
https://msdn.microsoft.com/en-us/library/ms141715.aspx
You map the business key which will check for existing record and you can insert/update. You can alter it to insert only.

I need to make sure 2 DB are the same

I'm doing it programmatically (I'm a newbie to sql) I'm getting the data per table within first DB using with being a value from a list of table names that I need to make sure are
there
if there have the corresponding values in the same table in
DB X list all the fields that do not have the same values and the
value in below
Table that does match listing the table, field name, row,
"SELECT * FROM [Dev.Chris21].[dbo].[" & PayrollTablemaskedarray(xxxxxx-2) & "]"
I can copy the whole thing into excel but I'm wondering is there a way to do this using sql?
Thanks
Since you mention that you're doing it programmically I assume you're using visual studio. If so you can take advantage of SQL Server Data Tools (SSDT) to do comparisons of two database schemas or two database data sets. You get this out of the box with VS2012 or VS2013 (and earlier versions too). Might be worth a look...

Adding a column to a table in SQLite

I've got a table in SQLite, and it already has many rows stored in it. I know realise I need another column in the table. Up to now I've just deleted the database and started again because the data has just been test data. But now the data in the database can't be deleted.
I know the query to add a column to the table, my question is what is a good way to do this so that it works for both existing users and new users? (I have updated the CREATE query I have for when the table is not found (because it's a new user or an existing user has cleared the database). It seems wrong to have an ALTER query in software that ships, and check every time. Is there some way of telling SQLite to automatically add the column if it doesn't exist during the UPDATE query I now need?
If I discover I need more columns in the future, is having a bunch of ALTER statements on startup (or somewhere?) really the best way to do it?
(If relevant this is for a node js app)
I'd just throw a table somewhere that marks what version of your database it is, and check that to determine if an update is needed. Either that or if you have a table already where there's always going to be just one record in it add a new field 'DatabaseVersion' to it.
So for example if you check the version number, and find it's a version 1 database when the newest version should be version 3, you know which updates to perform on it.
You can use PRAGMA user_version to store the version number of the database and check if the database needs to be updated.

Merging multiple Access databases into SQL Server

We have a program in which each user is given their own Access database. We'd like to merge these all together into a single SQL Server database.
The problem is that, using the SQL Server import/export wizard, the primary/foreign keys do not get updated. So for instance if one user has this table:
1 Apple
2 Banana
and another user has this:
1 Coconut
2 Cheeseburger
the resulting table looks like this:
1 Apple
2 Banana
1 Coconut
2 Cheeseburger
Similarly, anything that referenced Banana by its primary key (2) is now referencing both Banana and Cheeseburger, which will not make the vegans very happy.
Is there any way to automatically update the primary/foreign key references when importing, other than writing an extremely long and complex import-script?
If you need to keep them fully compartmentalized, you have to assign some kind of partitioning column to each table. Is there a reason you need your SQL Server to have the same referential integrity as Access? Are you just importing to SQL Server for read-only reporting? In that case, I would not bother with RI. The queries will all require a partitionid/siteid/customerid. You could enforce that for single-entity access by wrapping tables with a table-valued UDF which required the partitionid. For cross-site that doesn't work.
If you are just loading to SQL Server for reporting, I would also consider altering the data model to support reporting (i.e. a dimensional model is sometimes better than a normalized model) instead of worrying about transaction processing.
I think we need to know more about the underlying goals.
Need more information of requirements.
My basic question is 'Do you need to preserve the original record key?' e.g. 1:apple in table T of user-database A; 1:coconut in table T of user-database B. Table T is assumed to have the same structure in all database instances. Reasons I can suppose that you may want to preserve the original data: (a) you may have a requirement to the reference the original data (maybe a visual for previous reporting), and/or (b) there may be a data dependency in the application itself.
If the answer is 'no,' then you are probably interested only in preserving all of the distinct data values. Allow the SQL table to build using a new key and constrain the SQL table field such that it contains unique data. This approach seems to preserve the original table structure (but not the original key value or its 'location') and may suffice to meet your requirement.
If the answer is 'yes,' I do not see a way around creating an index that preserves a pointer to the original database and the key that was created in its table T. This approach would seem to require an application modification.
The best approach in this case is probably to split the incoming data into two tables: one to identify the database and original key, another to identify the distinct data values. For example: (database) table D has records such as 'A:1:a,' 'A:2:b,' 'B:1:c,' 'B:2:d,' 'B:15:a,' 'C:8:a'; (data) table T1 has records such as 'a:apple,' 'b:banana,' 'c:coconut,' 'd:cheeseburger' where 'A' describes the original database 'location,' 1 is the original value in location 'A,' and 'a' is a value that equates records in table D and table T1. (Otherwise you have a lot of redundant data in the one table; e.g. A:1:apple, B:15:apple, C:8:apple.) Also, T1 has a structure similar to the original T and is seems to be more directly useful in the application.
Ended up creating an SSIS project for this. SSIS is a visual programming tool made by Microsoft (and part of their "Business Integration Studio", which comes with SQL Server) designed for solving exactly these sorts of problems.
Why not let Access use its replication manager to merge the databases? This will allow you to identify the conflicts and resolve them before importing to SQL Server. I'm fairly confident it will retain the foreign key relationships. If I understand your situation correctly, and the databases are the same structure with different data, you could load the combined database to the application and verify the data before moving to SQL Server.
What version of Access are you using? Here's a link for Access 2000. Use the language to adjust search parameters to fit your version.
http://technet.microsoft.com/en-us/library/cc751054.aspx

Resources