SQL alter schema multiple tables at once - sql

I recently upsized my MS-Access database to SQL Server and in the process successfully exported a bunch of tables.
However, now the imported tables are prefixed with MSH-CHAMBERS\mfanimpela which I assume is my username and this is the schema (or owner property).
While I have seen posts on changing EACH table schema to the desired 'dbo', I want a statement that can help me change ALL of my tables (since these are so many).
Please help - chagbert.

Use the sp_MSForEachTable procedure like this:
EXEC **sp_MSForEachTable** 'ALTER SCHEMA dbo TRANSFER ?'
-- in the above example dbo is the targeted schema where you want to place your tables

Google sp_MSForEachTable and use it to call sp_rename
You might need to do additional checks before you rename the table to avoid mistakes.

Related

SQL Server - Ways of renaming a table name

I want to rename a table in SQL Server. I know the proper syntax would be:
sp_rename 'old table name','new table name';
Would it make any difference if I write it this way?:
EXEC sp_rename 'old table name','new table name';
I tried running it on SQL Server and without the EXEC, it would highlight my syntax sp_rename with red, but it doesn't throw any error.
Can anyone suggest the proper way or any other alternatives to rename a table?
Note: I know altering table name will affect or probably break the script and stored procedure, is there any way to prevent this? Or it only breaks if there is another table dependent on it?
You can execute a stored procedure with or without the EXEC Keyword. So Both your approaches are correct and has the same effect.
All the below 3 approaches are valid but the most commonly used is the 1st one
EXEC sp_rename 'old table name','new table name';
EXECUTE sp_rename 'old table name','new table name';
sp_rename 'old table name','new table name';
The easiest way would be to right click on the table name and click "rename". Both of your methods of using a proc are correct, though.
I would caution using this procedure though, especially in renaming stored procedures. It has been documented in many places that sp_rename fails to update the sys.procedures table which is often used to identify these objects within your database.

Using name of a database inside a sql script for a full table name

I struggled for a while with a bug, and then found out the reason for it in a database stored procedure code, which contained the old name of a database in a table name, whereas the current database name was already different. So, I'd like to ask:
Is there a situation in which using a database name as a part of a full table name (database name + schema name + table name) can be justified (provided we don't touch tables in other databases) or is it always a bad practice? How to correctly use a database name in sql scripts to keep code neutral to a specific database?
Code just for an illustration:
CREATE PROCEDURE [dbo].[MyProc]
AS
BEGIN
DELETE FROM [MyDatabase].[dbo].[MyTable]
END
No, you shouldn't use database names in a stored procedure unless you need to address two databases.
It causes exactly the kinds of bugs you're seeing. When the database name changes, all your SP code breaks, or continues working, but on the old database.
It does make sense if you are sending a SQL query to the database, but only if the application dynamically picks the database name to insert into the query.
My suggestion is that you do a full export of your database schema, and search for database names that are hardcoded and remove them.
It really depends on how your scripts are implemented.
Even if you don't refer to a table as
[MyDatabase].[dbo].[MyTable]
you will still need to refer to the database by:
USE [MyDatabase]
earlier in the script.
It is possible to mix trusted database tables in a single query. When someone do this,it is justified and mandatory to include database on table 'path'.
I don't found a reason out of this scenario if stored procedure and table is on the same database.
You can search all database name occurencies through database catalog in order to fix your development. For SQL Server 2005:
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%databasename%'
GO
For SQL Server 2000:
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%databasename%'
GO

Sql Server 2008 - Dropping a synonym

I have a utility database (customers) on my db server where I store all of the routines used to modify data on the other databases. We recently found out that using synonyms will greatly benefit us.
use Customers
IF EXISTS (SELECT * FROM employees.sys.synonyms WHERE name = 'tblPerson2') begin
drop synonym [dbo].tblPerson2
end
This doesn't work because I am using the Customers database but need to drop the synonym from my employees database.
SQL Server 2008 doesn't support this syntax -
drop synonym [employees].[dbo].tblPerson2
Anyone have any ideas on how to modify synonyms accross databases. My solution involves having to add an identical stored procedure to every database, which seems prone to error.
EXEC('USE employees;
DROP SYNONYM [dbo].tblPerson2;')

Copy data only between two databases

Im trying to copy data only between two SQL server 2008 databases. I need to keep the existing stored procs and functions intact and copy data only. The DB schemas are identical but im running into issues with PK's.
I first tried:
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
To remove all data. But get
Failure inserting into the read-only column
So i then tried to set IDENTITY_INSERT ON across all tables with:
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? SET IDENTITY_INSERT ON'
with no luck.
What is the best way to export data only between two databases, leaving the original procs and functions intact?
Thanks.
Edit: Im using SQL Export to copy the data from source to destination. I need to keep the destinations DBs procs and functions, just copy the data only.
Just remove the identity specification from all the table pkeys in the second db.
What is likely happening here is that you have pkey as an identity column in both dbs, and it makes sense to do so in the first, but you cant copy its value into another identity column.
You wouldn't want the pkey as an identity pkey in the second db anyway, then, all your foreign keys wouldn't work.
I would probably approach it from a different angle: by scripting all objects via SQL Enterprise Manager into a file and running this file on a blank database. This way, you'll have all metadata but no actual data in the second database, and you can use it for additional copies in the future.
The error you are getting doesn't seems like a PK violation or an Identity issue. I see two possible causes:
If you are getting the error when trying to insert the data, I would check if the tables have any computed columns. Many programs fail to take them into account when exporting data, and include the computed columns in the insert column list.
If you are getting that error in the delete step, probably you have a trigger that fires on delete, and it try to insert data and fails for some reason (the idea of these triggers is maintain a copy of the deleted data in another location). If that is the case, fix the insert or just disable the trigger.
I went with a varation of both answers this in the end. I used a 3rd database as a temp database.
1)I did a full back up of the database i needed the data from (live)
2)I restored this backup to my temp database.
3)I scripted the database i needed the procs and functions from, only scripting procs and funcs and using DROP and IF INCLUDES.
4)I ran the script from #3 against my temp database giving the data from DB1 and the procs and funcs from DB2
5)I restored DB2, using OVERWRITE from a backup of my temp database.
Thanks guys id mark all as correct if I could.
Hi in order to get around your issues with your constraints, please read this blog post I wrote on the subject.
http://tenbulls.co.uk/2009/07/22/checking-your-constraints-to-check-your-integrity/

Cleaning up a database

I have a database with hundreds of tables.
I am building a script to delete all of the rows in this database.
Of course, being a relational database, I have to delete rows from the children before I can touch the parents.
Is there something I can use for this or do I have to do this the hard way?
EDIT
Accepted Answer was modified to include Disable Trigger as well
EXEC sp_MSForEachTable 'DISABLE TRIGGER ALL ON ? '
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ENABLE TRIGGER ALL ON ? '
You can disable all the constraints, then delete all the data, and enable the constraints again. You can put the code in a stored procedure for reutilization. Something quick and dirty:
CREATE PROCEDURE sp_EmplyAllTable
AS
EXEC sp_MSForEachTable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL’
EXEC sp_MSForEachTable ‘DELETE FROM ?’
EXEC sp_MSForEachTable ‘ALTER TABLE ? CHECK CONSTRAINT ALL’
GO
I'm guessing you want the structure without any of the data?
Can you script the tables / sp's / user-defined functions / triggers / permissions etc. and then drop the database before recreating it with the script?
This link explains how to generate a script for all the objects in a database using SQL server Management studio... http://msdn.microsoft.com/en-us/library/ms178078.aspx
If this were MySQL, I would use "mysqldump --no-data" to make a backup of the database metadata only. Then I would drop the database entirely and restore my data-less backup.
In addition to being a three-step process, it is a lot faster just in terms of transactions and I/O than deleting from each table individually. And it also shrinks the tablespace on disk, which deleting would not do (for InnoDB, that is).
I'm not familiar with Microsoft SQL Server's backup tools, is there some equivalent option?
I think I've found something promising: How to: Generate a Script (SQL Server Management Studio)
To generate a script of an entire
database
In Object Explorer, connect to an instance of the SQL Server Database
Engine and then expand that instance.
Expand Databases, right-click any database, point to Tasks, point to
Generate Scripts, and then follow the
steps in the Generate Scripts Wizard.