Renaming ROWCOLGUID column when table has a FILESTREAM column - sql-server

I have a table for storing document content with a FILESTREAM column, and another column which is a ROWGUIDCOL column (required when you have a FILESTREAM column). I want to migrate this table with its existing data, into a slightly new structure as part of a code refactor so that 2 different projects can reuse code to manage their document records.
The problem is that I want to rename the ROWGUIDCOL column, so that both projects have the same column definitions for their document tables.
I can't use sp_rename because it doesn't work on ROWGUIDCOL columns.
I can't drop the existing ROWGUIDCOL column (and then add the replacement) because I get an error "A table that has FILESTREAM columns must have a nonnull unique column with the ROWGUIDCOL property."
I can't add the new ROWGUIDCOL column (and then drop the redundant original) because I get an error "Duplicate column specified as ROWGUIDCOL"
Is there any solution to this problem? Do I have to backup all the document content (the FILESTREAM column) and drop this first, then do the ROWGUIDCOL change, and then put the FILESTREAM content back in?

Consider creating the new table with a different name for the migration. Then load with INSERT...SELECT (mapping columns as desired), drop the original table, and finally rename the new table to the original name.

Related

Cannot delete column with only null values when BlockOnPossibleDataLoss=true

I'm using a blue-green deployment strategy with expand contract database pattern. To achieve that on my database deploy schema I've setted the property BlockOnPossibleDataLoss=true because on Expand phase I can modify my database without any break change with the old version.
I had a column that is not necessary anymore so I followed those steps:
I've changed this column to allow null values
Then my new records don't fill this column anymore
I ran a script that setted null for this column to all table records
Now I need to delete this column, but even with all records with NULL value for this column I can't because I got this error:
Rows were detected. The schema update is terminating because data loss
might occur.'
How can I delete this column even using BlockOnPossibleDataLoss=true?
Create the table with the new schema (without the column you wan't to drop) with a temporary name. Something like tmp_YourTable (Not a temporary table)
Insert all data from the source table, to the newly created table
Drop the source table
Rename the new table, to the old table name. EXEC sp_rename 'tmp_YourTable', 'YourTable';

SQL Server 2012: ALTER TABLE ALTER COLUMN MyColumn1 fails because one or more objects access this column

I have a table which contains MyColumn1 with user defined datatype of CustomDatatype INT NOT NULL. I need to change this column to a VARCHAR(5), but I am getting the following errors:
Msg 5074, Level 16, State 1, Line 12
The object 'CustomDatatype' is dependent on column 'MyColumn1'.
Msg 4922, Level 16, State 9, Line 12
ALTER TABLE ALTER COLUMN MyColumn1 failed because one or more objects access this column.
This does not seem to be related to an index or foreign key reference which I would omit to drop before altering the column datatype, this seems to be directly related to the originally used custom defined datatype CustomDatatype on this column.
How can I change MyColumn1's datatype without dropping the CustomDatatype because that could create apocalyptic scenario in my system or dropping the table?
Thanks
Update (2018-07-31): I found a response to the same question in different forum where it states: "...This is the problem with UDT columns. You will need to drop all the columns of this type first in all tables (and may be in functions / SPs, views), then delete the type and create correct type, then re-create all the columns..." (Naomi 2011) from Microsoft (August 2, 2011) web: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/b7bf0f04-dee8-4751-803b-4c3e1f7f7c70/how-to-change-column-nametype-of-user-defined-table-type?forum=transactsql
So far the only viable solutions I came up with are to:
Create a copy of the table (script it out with all
dependencies i.e.: triggers, indexes, keys, etc.) Drop the original
table (which is ok to do even though custom datatypes are specified) and then recreate the table again with the new datatype column.
If the table cannot be dropped (for some reason) rename the old
datatype column, create a new column with the original column name
with the right datatype. Move the data from the old (renamed) column
into the new one (make sure to mind the triggers,etc.). Then force
to recompile all the Sprocs and refresh all the views which are
dependent.
Can you check if there is any Index added for those column?
If yes,
you will need to drop and recreate the index.
once you drop the constraints and index , you can alter the column.
alter table Table1
alter column MyColumn1 varchar(5);
Then re-create constraints and index.
So far the only viable solutions I came up with are to:
1) Create a copy of the table (script it out with all dependencies i.e.: triggers, indexes, keys, etc.) Drop the original table (which is ok to do even though custom datatypes are specified) and then recreate the table again with the new datatype column.
2) If the table cannot be dropped (for some reason) rename the old datatype column, create a new column with the original column name with the right datatype. Move the data from the old (renamed) column into the new one (make sure to mind the triggers,etc.). Then force to recompile all the Sprocs and refresh all the views which are dependent.

Update table with two columns as unique constraints in SQLite, NOT create table again

I want to update table in my SQLite database and add UNIQUE contraint to two columns in my Data table.
Here is what I was trying , but throws error.
ALTER TABLE Data
ADD CONSTRAINT Data UNIQUE(id, dateofday);
All previous answers are on create table which I don't want. Any Suggestion?
It is not possible.You cannot add a constraint to an existing table in sqlite. You can only rename table or add columns to a table.
Link for your reference : http://www.sqlite.org/lang_altertable.html
However you can use this alternate approach to achieve the same.
Create a temporary table with the same columns as your current table with all the constraints you need.
Then move all the data from the old table to the new temporary table with constraints defined using
INSERT INTO Destination SELECT * FROM Source;
Check if you have copied all the data from the original table to temporary table.
Drop your original table and rename the temporary table to the name of the original table.

Custom UniqueId for merge replication on sql server 2008?

When doing merge replication, is the column ROWGUIDCOL compulsory? Can I use a custom column I have created that will be unique across all databases?
Does this mean I have to use GUID as my primary key or can i have a gUID column and my custom id column as well?
When I try to create a merge replication, it wants to add a guid column and I am not sure if thats what i want to do.
Any suggest a stragety to create a merge replication? I really want to avoid using a guid as my primary key on all tables...this would also create a alot of work for our application
Per Considerations for Merge Replication, each published table requires a GUID column with the ROWGUIDCOL property set and a unique index.
Merge replication uses a globally unique identifier (GUID) column to
identify each row during the merge replication process. If a published
table does not have a uniqueidentifier column with the ROWGUIDCOL
property and a unique index, replication adds one. Ensure that any
SELECT and INSERT statements that reference published tables use
column lists. If a table is no longer published and replication added
the column, the column is removed; if the column already existed, it
is not removed.

Converting int primary key to bigint in Sql Server

We have a production table with 770 million rows and change. We want(/need?) to change the Primary ID column from int to bigint to allow for future growth (and to avoid the sudden stop when the 32bit integer space is exhausted)
Experiments in DEV have shown that this is not as simple as altering the column as we would need to drop the index and then re-create it. So far in DEV (which is a bit humbler than PROD) the dropping of the index has not finished after 1 and a half hours. This table is hit 24/7 and having it offline for such a long time is not an option.
Has anyone else had to deal with a similar situation? How did you get it done?
Are there alternatives?
Edit: Additional Info:
The Primary key is clustered.
You could attempt a staged approach.
Create a new bigint column
Create an insert trigger to keep new entries in sync with the 2 columns
Execute an update to populate all the empty values in the bigint column with the converted value
Change the primary index on the table from your old id column to the new one
Point any FK's and queries to use the new column
Change the new column to become your identity column and remove the insert trigger from #2
Delete the old ID column
You should end up spreading the pain out over these 7 steps instead of hitting it all at once.
Create a parallel table with the longer data type for new rows and UNION the results?
What I had to do was copy the data into a new table with the desired structure (primary/clustered key only, non-clustered/FK once complete). If you don't have the room, you could bcp out the data and back in. You may need an application outage to make this happen.
What doesn't work: alter table Orderhistory alter column ID bigint because of the primary key. Don't drop the key and alter column as you will just fill your log file and take much longer than copy/bcp.
Never use the SSMS tools designer to change a column property, it copies table into temp table then does a rename once done. Lookup the alter table alter column syntax and use it and possibly defrag once complete if you modified a column wider that sits in middle of table.

Resources