I have a database that is used to transfer data across the main production database when we import data from a third party.
I would like to add an Identity column to each table.
I know that the below SQL will do for a single table, how can I do it for all the tables in the database?
ALTER TABLE dbo.YourTable
ADD Id INT IDENTITY(1,1) NOT NULL
Many thanks
You'll have to do it one table at a time - there's no "magic" way to do it to all tables at once.
You can have SQL Server generate the T-SQL statements needed for that operation by inspecting the sys.tables catalog view - assuming you want to call that identity column Id for all tables:
SELECT
t.NAME,
'ALTER TABLE [' + SCHEMA_NAME(t.SCHEMA_ID) + '].[' + t.NAME +
'] ADD Id INT IDENTITY(1,1) NOT NULL'
FROM
sys.tables t
Now, copy & paste the resulting lines of this statement and execute those lines against your database - and you're done!
U can use 'sp_MSforeachtable 'And add to Every table in your Database
just run this query:
EXEC sp_MSforeachtable '
if not exists (select * from sys.columns
where object_id = object_id(''?'')
and name = ''ColName'')
begin
ALTER TABLE ? ADD ColName <DataType> NULL ; // or NOT NULL DEFAULT
<DefaultValue>;
end';
If you are using an Azure SQL,This Stored Procedure is not available under programmability.
Either you can port it from your master database from your on-prem sql server.Or use this link to the run the stored procedure
https://gist.github.com/metaskills/893599
Related
I have 4 columns that are repeated in all the tables in the database and I have to delete them
How can I do this deletion without having to enter table by table?
This code will output the necessary SQL to make the changes.
STRING_AGG is used twice to group up the columns and tables. QUOTENAME is used to place brackets around names correctly.
SELECT STRING_AGG(
N'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(t.object_id) + N'
' + c.ColumnSql, N'
')
FROM sys.tables t
CROSS APPLY (
SELECT ColumnSql = STRING_AGG(CAST(N'DROP COLUMN ' + QUOTENAME(c.name) AS nvarchar(max), N'
')
FROM sys.columns c
WHERE c.object_id = t.object_id
AND c.name IN (
'ID_Integracion_CodBodega',
'ID_Integracion_FechaUltRep',
'ID_Integracion_ControlTrigger',
'ID_Integracion_CodBodega_Origen'
)
) c
You can execute it all together by using
DECLARE #sql nvarchar(max) = (
SELECT STRING_AGG.....
);
EXEC(#sql);
I caution you against using INFORMATION_SCHEMA because it is only there for compatibility.
SQL Server provides system information schema views that can be queried to retrieve information about the database.
In your case, the COLUMNS view can be used to fetch the names of all tables containing a specific column name.
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN (
'ID_Integracion_CodBodega',
'ID_Integracion_FechaUltRep',
'ID_Integracion_ControlTrigger',
'ID_Integracion_CodBodega_Origen'
);
From there, you can use the normal process to delete a column from an existing table.
ALTER TABLE [table_name] DROP COLUMN [column_name];
You should be very careful with this approach. It is easy to drop a column you didn't mean to.
Be aware of any constraints/dependencies in your database schema that you might be affecting with this action.
Are there constraints on your tables that will be affected by the removal of these columns? (Especially ON DELETE CASCADE constraints that may impact other tables).
Are there views/stored procedures/triggers that depend on these columns?
Do you have queries/dynamic SQL that will be impacted by the removal of these columns?
This is my first time posting on SO, so please go easy!
I'm attempting to write a SQL script that queries the same table for a list of databases in a single SQL Server instance.
I have successfully queried the list of databases that I required using the following, and inserting this data into a temp table.
Select name Into #Versions
From sys.databases
Where name Like 'Master%'
Master is suffixed with numerical values to identify different environments.
Select * From #Versions
Drop Table #Versions
The table name I am trying to query, is the same in each of the databases, and I want to extract the newest value from this table and insert it into the temp table for each of the database names returned.
I have tried researching this but to no avail. I am fairly comfy with SQL but I fear I could be out of my depth here.
You can do the following. Once you have the list of your databases, you can build up the query (you need to edit it for your purpose).
Select name Into #Versions
From sys.databases
Where name Like 'test%'
declare #sql as varchar(max) = ''
select #sql = #sql + 'INSERT INTO sometable SELECT TOP 1 * FROM ' + name + '..sourcetable ORDER BY somedate DESC; '
FROM #Versions
exec (#sql)
Drop Table #Versions
Look at The undocumented sp_MSforeachdb procedure and here
I want to change schema name of table Employees in Database. In the current table Employees database schema name is dbo I want to change it to exe. How can I do it ?
Example:
FROM
dbo.Employees
TO
exe.Employees
I tried with this query:
ALTER SCHEMA exe TRANSFER dbo.Employees
But this gives me an error:
Cannot alter the schema 'exe', because it does not exist or you do not
have permission.
What did I miss?
Create Schema :
IF (NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'exe'))
BEGIN
EXEC ('CREATE SCHEMA [exe] AUTHORIZATION [dbo]')
END
ALTER Schema :
ALTER SCHEMA exe
TRANSFER dbo.Employees
ALTER SCHEMA NewSchema TRANSFER [OldSchema].[TableName]
I always have to use the brackets when I use the ALTER SCHEMA query in SQL, or I get an error message.
Try below
declare #sql varchar(8000), #table varchar(1000), #oldschema varchar(1000), #newschema varchar(1000)
set #oldschema = 'dbo'
set #newschema = 'exe'
while exists(select * from sys.tables where schema_name(schema_id) = #oldschema)
begin
select #table = name from sys.tables
where object_id in(select min(object_id) from sys.tables where schema_name(schema_id) = #oldschema)
set #sql = 'alter schema ' + #newschema + ' transfer ' + #oldschema + '.' + #table
exec(#sql)
end
CREATE SCHEMA exe AUTHORIZATION [dbo]
GO
ALTER SCHEMA exe
TRANSFER dbo.Employees
GO
Through SSMS, I created a new schema by:
Clicking the Security folder in the Object Explorer within my server,
right clicked Schemas
Selected "New Schema..."
Named my new schema (exe in your case)
Hit OK
I found this post to change the schema, but was also getting the same permissions error when trying to change to the new schema. I have several databases listed in my SSMS, so I just tried specifying the database and it worked:
USE (yourservername)
ALTER SCHEMA exe TRANSFER dbo.Employees
Your Code is:
FROM
dbo.Employees
TO
exe.Employees
I tried with this query.
ALTER SCHEMA exe TRANSFER dbo.Employees
Just write create schema exe and execute it
Check out MSDN...
CREATE SCHEMA: http://msdn.microsoft.com/en-us/library/ms189462.aspx
Then
ALTER SCHEMA: http://msdn.microsoft.com/en-us/library/ms173423.aspx
Or you can check it on on SO...
How do I move a table into a schema in T-SQL
Make sure you're in the right database context in SSMS. Got the same error as you, but I knew the schema already existed. Didn't realize I was in 'MASTER' context. ALTER worked after I changed context to my database.
In case, someone looking for lower version -
For SQL Server 2000:
sp_changeobjectowner #objname = 'dbo.Employess' , #newowner ='exe'
Be very very careful renaming objects in sql. You can cause dependencies to fail if you are not fully away with what you are doing. Having said that this works easily(too much so) for renaming things provided you have access proper on the environment:
exec sp_rename 'Nameofobject', 'ReNameofobject'
also you can transfer your data from default schema 'dbo' to your schema
from wizard by
1-double click on db diagram
2- right click on your certian entity --> select properties
3- on right at identity , change the schema name
For SQL2019:
ALTER SCHEMA [SCEMAYOUWANTTOTRANSFERTO] TRANSFER [CURRENTSCHEMA].[TABLENAME];
Example:
ALTER SCHEMA [dbo] TRANSFER [Curated].[MyTable];
DECLARE #tmp_tab VARCHAR(20)
SELECT #TMP_TAB = '#TMP_TAB_BANK' + CAST(USER_ID(USER) AS NVARCHAR)
+ CAST(##SPID AS NVARCHAR)
EXEC('CREATE TABLE ' + #TMP_TAB + (ID INT NULL, NAME VARCHAR NULL)')
//Break point
EXEC('select * from ' + #TMP_TAB)
I'm working in SQL Server 2005. In the code above I decide what to name my temp table. Then I create the temp table. If I run just these codes I receive Commands completed successfully message.
However if I execute the last line of code to retrieve the data (well, I know it's empty) I get
invalid object name '#TMP_TAB_BANK157'
Why can't I fetch records from a just created table? If the temp table was not created then why don't I get any warning?
#TEMP tables are only available from the context they are created in. If you create #temp1 in one spid or connection, you can't access it from any other scope, except for child scopes.
If you create the #TEMP table in dynamic SQL, you need to select from it in the same scope.
Alternatives are:
##GLOBAL temp tables, which have their own risks.
Real tables
I have created many tables on my local database and moved them to production database.
Now I am working on fine tuning the database and created many constraints on my local database tables such as PK, FK, Default Values, Indexes etc. etc.
Now I would like to copy only these constraints to production database. Is there a way to do it?
Please note that my production database tables already populated with some data. So I can’t drop and recreate them.
If you don't want to buy any tools (which are totally worth their price, BTW), you can always interrogate the system catalog views, and extract the info from there to create scripts you could execute on your new database.
In the case of e.g. the default constraints, this query shows you a list of all the default constraints in your database:
SELECT
dc.name 'Constraint Name',
OBJECT_NAME(parent_object_id) 'Table Name',
c.name 'Column Name',
definition
FROM
sys.default_constraints dc
INNER JOIN
sys.columns c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
ORDER BY
OBJECT_NAME(parent_object_id), c.name
and based on that, you could of course create a query which would emit T-SQL statements to recreate those default constraints on your target server:
SELECT
'ALTER TABLE ' + OBJECT_SCHEMA_NAME(dc.parent_object_id) + '.' + OBJECT_NAME(dc.parent_object_id) +
' ADD CONSTRAINT ' + dc.name + ' DEFAULT(' + definition
+ ') FOR ' + c.name
FROM
sys.default_constraints dc
INNER JOIN
sys.columns c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
You'd get something like this (for the AdventureWorks sample DB):
ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_rowguid DEFAULT((newid())) FOR rowguid
ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.ProductPhoto ADD CONSTRAINT DF_ProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_Primary DEFAULT(((0))) FOR Primary
ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_rowguid DEFAULT((newid())) FOR rowguid
ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.Address ADD CONSTRAINT DF_Address_rowguid DEFAULT((newid())) FOR rowguid
Of course, you could tweak the resulting T-SQL being output to your liking - but basically, copy&paste those results from the query to your new database, and off you go.
Of course, there are similar system catalog views for foreign key relationships (sys.foreign_keys), check constraints (sys.check_constraints), indexes (sys.indexes and sys.index_columns) and many more.
It's a bit of work - but it can be done on your own time, and you'll learn a lot about SQL Server in the process.
So it's a traditional "make or buy" decision all over again :-)
Marc
The best way would be to store all your DDL code in a source control. Then deploy it to production using tools like dbGhost (my favorite) or SQL Compare
Red Gate's SQL Compare is a popular, non-free way to do this.
Sure this is an old post, but none of the scripts in all the above answers put out the table schemas as well. So it didn't work out the box for my database.
This one does, so it did:
-- ===========================================================
-- Default Constraints
-- How to script out Default Constraints in SQL Server 2005+
-- ===========================================================
-- view results in text, to make copying and pasting easier
-- drop default constraints
SELECT
'ALTER TABLE ' +
QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QUOTENAME(OBJECT_NAME(sc.id)) +
CHAR(10) +
' DROP CONSTRAINT ' +
QuoteName(OBJECT_NAME(sc.cdefault))
FROM
syscolumns sc
INNER JOIN
sysobjects as so on sc.cdefault = so.id
INNER JOIN
syscomments as sm on sc.cdefault = sm.id
WHERE
OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
-- create default constraints
SELECT
'ALTER TABLE ' +
QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QuoteName(OBJECT_NAME(sc.id)) +
' ADD CONSTRAINT ' +
QuoteName(OBJECT_NAME(sc.cdefault))+
' DEFAULT ' +
sm.text +
' FOR ' + QuoteName(sc.name)
+ CHAR(13)+CHAR(10)
FROM
syscolumns sc
INNER JOIN
sysobjects as so on sc.cdefault = so.id
INNER JOIN
syscomments as sm on sc.cdefault = sm.id
WHERE
OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
I adapted it from Donabel Santos's blog here.
EDIT and NB: Be sure to run both parts of the query and save the second result set (i.e. ADD CONSTRAINTs) before dropping your default constraints, else you won't be able to re-create them again (no I didn't do that :)
A good and free Microsoft tool. You can export the schema and the data.
Microsoft SQL Server Database Publishing Wizard
Try DBSourceTools. http://dbsourcetools.codeplex.com
It has schema compare function that will help you create an update script.
Bear in mind though, that you should be using source-code control on your entire database.
This is what DBSourceTools was designed to do - help developers bring their databases under source control.