views:

61

answers:

2

Using SQL Server and T-SQL, how can I update ALL tables tables with a specific name but different schemas under the same database?

:Update:

The updates include adding/deleting/modifying columns as well as changing specific values of rows.

I want to be able to deploy changes to a table across all schemas. Using the SQL Server Management Studio table designer, when I do a change and save, it allows me to save a script that can be used to deploy those changes to a different table. I want to be able to use that script on all tables with that specific name across all schemas.

:Update 2:

There reason for this request is that I want to ensure that updating a specific table across multiple schemas is easy to do. In the future, my application will undoubtedly change and if I see that it is difficult or inefficient to update schemas then I will opt to use something else.

Below is what I tried:

DECLARE @update_sql NVARCHAR(max)
DECLARE @table_name VARCHAR(45)

DECLARE c_tables CURSOR FOR
  SELECT t.table_name
    FROM INFORMATION_SCHEMA.TABLES t
   WHERE t.table_name = 'TestTable'
     AND t.table_catalog = 'MyDataBase'

OPEN c_tables
FETCH c_tables INTO @table_name

WHILE @@Fetch_Status = 0
BEGIN

  SET @update_sql = N'ALTER TABLE '+@table_name+' ADD ColumnThree nvarchar(50) NULL'
  EXEC sp_executesql @update_sql

END

CLOSE c_tables
DEALLOCATE c_tables

Running this generates the following error:

Cannot find the object "TestTable" because it does not exist or you do not have permissions.

The table exists and I'am running under dbo which is the schema owner.

I also noticed the query takes sometime to run even with only 7 tables in the database and 3 schemas used on those tables. Would it be more efficient to just login with each schema's owner and run a generic script? Each schema owner would only have access to their respective schema and tables.

+4  A: 

On SQL Server 2005+, you can use INFORMATION_SCHEMA.TABLES to get a list of tables within a database:

SELECT t.table_name,
       t.table_schema
  FROM INFORMATION_SCHEMA.TABLES t
 WHERE t.table_name = 'Table_1'
   AND t.table_catalog = 'your_database'

But you didn't specify what updating you need - DML or DDL...

Update

DECLARE @update_sql NVARCHAR(max)
DECLARE @table_name VARCHAR(45)

DECLARE c_tables CURSOR FOR
  SELECT t.table_name
    FROM INFORMATION_SCHEMA.TABLES t
   WHERE t.table_name = 'Table_1'
     AND t.table_catalog = 'your_database'

OPEN c_tables
FETCH c_tables INTO @table_name

WHILE @@Fetch_Status = 0
BEGIN

  SET @update_sql = N'UPDATE @table_name SET ...'
  EXEC sp_executesql @update_sql

  SET @update_sql = N'ALTER TABLE @table_name ...'
  EXEC sp_executesql @update_sql

END

CLOSE c_tables
DEALLOCATE c_tables
OMG Ponies
Assuming DDL or DML, how can this be used?
Baddie
@Baddie: You need to use dynamic SQL because you can't specify a variable for a table name in DDL or DML statements, beyond that - a cursor loop.
OMG Ponies
@OMG Ponies - Take a look at update 2 please.
Baddie
@Baddie: I noticed when I was testing that INFORMATION_SCHEMA.TABLES only runs in the context of the current database. IE - I only found my tables in AdventureWorks but not when running within say master or tempdb...
OMG Ponies
+3  A: 

You can use sp_MSforeachtable if the action will be the same on all (I'd obviously put some pretty robust error handling and rollback facilities into the scripts first)

exec sp_MSforeachtable 
   '
    if parsename(''?'',1) = ''TargetTableName''
    begin
    update ? set ColumnToUpdate=NewValue;

    execute sp_rename N''?.newname'', N''obsoletename'', ''column'' ;

    alter table ? add newcol int null;

    alter table ? drop column oldcol;
    end'
Martin Smith
This worked perfectly, however, I am having issues using `TRANSACTIONS` inside of it, is this not allowed?
Baddie
What issue are you getting? I just tried `exec sp_MSforeachtable 'set xact_abort on begin tran select count(*) from ? commit'` and didn't get any errors.
Martin Smith
Also, when using a complex query, like the ones generated by SQL Server Management Studio when a table is edited, how can I have any `CREATE TABLE` commands use the current table's schema? This is needed when a temp table -> drop original -> rename temp sequence.
Baddie
@Baddie. You're probably best off using @OMG Ponie's answer for more complex scenarios. I think you just need to take account of the schema in that query (e.g. with `QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_CATALOG)`)
Martin Smith