How can I drop and recreate all dependencies (keys, constraints, and views) for altering columns? - sql

I want to alter all varchar columns in my database to nvarchar, using a T-SQL script.
There are a lot of dependencies (keys, constraints, and views) that cause problems when trying to alter.
The object 'X' is dependent on column 'Y'. ALTER TABLE ALTER COLUMN 'Y' failed because one or more objects access this column.
My unsuccessful attempts: forcing a change with PowerShell, and creating a generate script for the whole database and using that to create a copy with all the changes I need. These attempts didn't work, because I lost the table data and the generate scripts were too big for any program to handle.
How does one create all DROP and CREATE scripts of the objects that cause problems when trying to alter to make the changes and recreate the database schema like it was before altering?

Related

How to repeat multi-step schema change (ETL schema changes?)

I'm new to DBA and not much of a SQL person, so be gentle please.
I'd like to restructure a database that requires adding new columns, tables, and relationships followed by removing old tables, columns, and relationships. A three step process seems to be in order.
Change schema to add new stuff
Run SSIS to hook up new data using some of the old data.
Change schema to drop old stuff.
I'm using a SQL database Project in VS 2015 to maintain the schema, and using schema compare to update the DB schema. I'd like to make it repeatable or automatic, if possible, so I can test it out on a non-production database to get the flow right: change schema->run ETL->change schema. Is there a way to apply schema changes from within ETL or does this require manual operations? Is there a way to store two schemas into files and then apply them, other than VS publish or compare?
There is a SQL TASK that allows you to do what you want to do. You want to alter table (to add columns), move the data from old columns to new columns, then drop the old columns.
1) Alter table tableA add column ..
2) update table tableA set ..
3) alter table tableA drop column...
Please test your code carefully before running it.
It worked! Here is the example of the ETL. Note that it's important to set DelayValidation to true for the data flows and to disable ValidateExternalMetadata for some of the operations within the data flows because the database is not static.

Why alter command is referred as DDL and not DML?

I was going through the different commands in SQL and I came across alter command which is referred as DDL (Data Definition Language). We can alter the column and values in it, so we can manipulate the data with this command so why does alter command is not referred as DML (Data Manipulation Language).
I have googled and I can not come across some good explanation, so please help me with this.
ALTER command is used to alter the structure of the database. And this is what DDL does i.e., DDL statements are used to define the database structure or schema.
Whereas DML statement is used to manage data within schema objects.
DDL - alter the schema.
This including creating tables, renaming columns, dropping views, etc. Such statements are DDL even though such might create (default value), alter (by conversion), or even lose (removed column) data as part of the process. Basically, any CREATE/DROP/ALTER command is DDL.
DML - alter the information/data within the schema; without updating the schema.
This includes DELETE and UPDATE statements.
Sometimes DDL and DML must be used together to correctly migrate a schema; but they are two distinct categories of SQL commands, and DML never causes the schema to be changed.
Cause ALTER command is not manipulating the data. It is used to change a definition of o column or table or other DB objects.
See
http://www.w3schools.com/sql/sql_alter.asp
The "data" is the data in the tables defined by the user via DDL. The "metadata" is the data in the tables pre-defined by the DBMS that describe the tables (themselves and those defined by the user). So DML manipulates data in user tables or (usually only) reads metadata from system tables while DDL defines (CREATEs, ALTERs, DROPs) user tables and as a side effect updates metadata in system tables.
The ALTER command can be both DDL and DML. I have known ALTER to be DDL over the past just like the majority of those who have responded to this. However, with MySQL 5.7.x you will see that soon after initializing the database with mysqld --initialize --console a default root user account and its corresponding password is created. You can access your database with this newly created root user account BUT there is absolutely nothing that you can do after logging in. The only SQL statement allowed at this stage is the ALTER statement. This is used to change the default password generated during initialization. The syntax is ALTER USER 'root'#'localhost' IDENTITIED BY 'new_password'; . This is the only statement that the database accepts. This modifies/updates/manipulates the data (password) in the users table. In this regard I have concluded that the ALTER statement can be both DDL and DML

Change column type from bigint to numeric(18,0) in sql server

I have around 10 tables which have data in them. I need to change the fields which have data type bigint to numeric(18,0).
We have verified data in our DB, there would not be any data loss. In our lower environment, what we have done is:
Took backup for existing table, renamed it temporarily
Create a new table with numeric data type
Populate data from backup table
If everything is okay, then delete backup table
The above is the process we have followed in lower environments.
But, we cannot follow above procedure when it comes to prod. We would like to change using ALTER statement. Since it is PROD environment, we have to be careful with changes. As I said earlier, there would not be any data loss.
But still wanted to know - what internally happens when we execute the ALTER statement?
Will it drop the table and recreate it with new definitions and populate the data back? If so, are there any risk associated with this?
Any thoughts on how this could be properly handled in PROD would be appreciated.
I might suggest an approach that doesn't rebuild the data. Use a computed column instead. Something like this:
sp_rename 'table.dbo.col', '_col', 'COLUMN';
alter table table add col as (cast(_col as numeric(18, 0));
You can then access col as the type that you want. You will not have to rewrite any data, so there will not be any locks or other issues with performance. Of course, select * will be a bit redundant, but you probably shouldn't be doing that anyway.

Renaming SQLite Tables/Columns/Rows after indices have been created

If I rename SQLite Tables/Columns/Rows after indices have been created, will the old indices still be functional?
Thanks!
If you're using ALTER TABLE with RENAME TO to rename a table, then as described on this page (from the sqlite docs) the indices will still work:
The ALTER TABLE command in SQLite allows the user to rename a table [...] If the table being renamed has triggers or indices, then these remain attached to the table after it has been renamed.
But note there's no renaming of columns allowed. This is one of the SQL features not implemented by sqlite:
Only the RENAME TABLE and ADD COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.
Rows don't have names (except in the sense of having a PK) so there's not really a way of renaming them.
I highly recommend using Rails ActiveRecord migrations to maintain your database. This can be done outside of Rails. So you app doesn't need to be a Rails app to use rake tasks
See here for an excellent blog on how to do this http://exposinggotchas.blogspot.com/2011/02/activerecord-migrations-without-rails.html
Yes, the old indices will still be functional.
Be aware, that sqlite doesn't care about the names for the indexes. Initially when an index is created usually they are named after the table and field, so when you rename the table, the indexes will still have the name of the old table in it. This can cause problems, when you for example:
dump the table
rename the old table:
sqlite3 "$DB" "PRAGMA busy_timeout=20000; ALTER TABLE '$TABLE' RENAME TO '$TABLE"_backup"'"
reimport the dumped table
This will cause an error, that the indexes already exist.
Solution: Rename the indexes too, or delete them in the renamed table before you reimport the original (see this answer).

Inconsistent Generate Change Script

I add a column of type tinyint and being set to not allow nulls in a table and generate the change scripts. The table has data in it at this time. The script has code that creates a temp table and inserts the data that is in the current table into. It then deletes the old table and renames this temp table to the same name as the original table. All fine and good. My question is, why if I do the same thing to another table (same field, but different table), the generate change script does not include this new table insertion code?
Any tips would be greatly appreciated!
If the table does not contain data, there is no need to rebuild the table. Essentially Management Studio "plays it safe" behind the scenes by generating the script this way if it thinks it can't do it simply by just modifying the table. In my experience, it often does this when it doesn't really need to, however there are exceptions ... for example if you add your column not at the "end" of the table. Rather than make changes in the UI and script them, I recommend becoming familiar with the ALTER TABLE command. Rebuilding the table in that manner can be catastrophic on a production system, and can usually be avoided.