I inherited a large database with many tables and related databases. They had used an identifying value of VARCHAR(8) this is used in different tables.
Now we want to make these improvements:
modify this column to be of type VARCHAR(20)
add a Unique ID that would be an INT.
How can I make a unique ID column and values for multiple tables and databases?
You can run below query in your database and copy result of the query into new window to change data type. Similarly you can build query to add column.
select 'ALTER TABLE ' + t.TABLE_NAME + ' ALTER COLUMN ' + column_name + ' VARCHAR(20)'
from INFORMATION_SCHEMA.TABLES t
join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_NAME = c.TABLE_NAME
where c.COLUMN_NAME = 'Col1'
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?
I want to write a SELECT statement to show the list of fields in the table.
COLUMN
column_1
column_2
column_3
You can use the information schema tables, particularly columns:
select column_name
from INFORMATION_SCHEMA.COLUMNS
where table_schema = #schema_name and table_name = #table_name;
Note that this metadata is stored per database. So if you want a table in another database, you need three part naming:
select column_name
from <database>.INFORMATION_SCHEMA.COLUMNS
where table_schema = #schema_name and table_name = #table_name;
Yet one more option: This will return results on any table,ad-hoc query or even a stored procedure.
(using spt_values as a demonstration)
Example
Select column_ordinal
,name
,system_type_name
From sys.dm_exec_describe_first_result_set('Select * From master..spt_values',null,null )
Returns
In SQL Server you can also highlight the tablename in a query then press ALT+F1 to show the highlighted table info.
I have a database with 1000s of tables. I want to drop all of them except say 15 of them.
Is there a quick way to do this?
You can run the below sql statement and get the list of tables you want then copy and paste the results to actually drop the tables.
SELECT 'drop table ' + t.TABLE_SCHEMA + '.' + T.TABLE_NAME + ';'
FROM INFORMATION_SCHEMA.tables t
WHERE table_name LIKE '%bob%'
I need to reset collation for all columns in all tables in the database:
I want to use default collation of database
I tried to change it under database properties:
but collation already setted in columns and it mean that i cannot overwrite it
anybody has script that can do it for me?
I've knocked together a script that should do a decent enough job (hopefully). Run the script in the appropriate database, with results as text. Then Copy & Paste the output into a script window to change the collation of each column:
declare #NewCollationName sysname
set #NewCollationName = 'Latin1_General_CS_AS'
select
'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(st.schema_id)) + '.' + QUOTENAME(st.name) +
' ALTER COLUMN ' + QUOTENAME(sc.name) + ' ' + styp.name + '(' +
CASE WHEN sc.max_length = -1 THEN 'max' ELSE CONVERT(varchar(10),sc.max_length) END +
') collate ' + #NewCollationName + '
go
'
from
sys.columns sc
inner join
sys.tables st
on
sc.object_id = st.object_id
inner join
sys.types styp
on
sc.user_type_id = styp.user_type_id
where
sc.collation_name is not null and
OBJECTPROPERTY(st.object_id,N'IsMSShipped')=0
One thing to note, however, is that the generated script won't work if the columns are the target of constraints or targetted by a schema bound object (view or function).
In such cases, you'd have to script out the dependent objects, drop them from the database, then run the script generated by the script above, and finally re-add the dependent objects.
See (Changing the Database Collation) http://msdn.microsoft.com/en-us/library/ms174269.aspx
ALTER DATABASE database_name COLLATE collation_name
The fastest way to reset a column would be to SET UNUSED the column, then add a column with the same name and datatype.
This will be the fastest way since both operations will not touch the actual table (only dictionary update).
The actual ordering of the columns will be changed (the reset column will be the last column). If your code rely on the ordering of the columns (it should not!) you can create a view that will have the column in the right order (rename table, create view with the same name as old table, revoke grants from base table, add grants to view).
The SET UNUSED method will not reclaim the space used by the column (whereas dropping the column will free space in each block).
Hope this helps.
A proposed script (can be found here) is meant to iterate through all tables in your DB and changing the collation to the desired one.
It is based on the script:
ALTER TABLE TABLENAME ALTER COLUMN COLUMNNAME varchar(100) COLLATE Latin1_General_CI_AS NULL
How can I Select all columns from all tables from the DB, like:
Select * From *
in SQL Server 2008???
The table list it´s very very big, and have so many columns, is it possible to do it without writing the column names?
Or maybe make a select that returns the name of the tables.
This SQL will do this...
DECLARE #SQL AS VarChar(MAX)
SET #SQL = ''
SELECT #SQL = #SQL + 'SELECT * FROM ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
EXEC (#SQL)
Try this, works fine
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
then you could add
WHERE TABLE_NAME LIKE '' AND COLUMN_NAME LIKE ''
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID where t.name = 'ProductItem' AND C.name like '%retail%'
ORDER BY schema_name, table_name
It is possible to retrieve the name of all columns from sys.columns
It is possible to retrieve the name of all table from sys.tables
But is impossible to retrieve all the data from all the tables. As soon as more than one table is involved in a query, a JOIN is necessary. Unless join conditions are provided, tables are joined as full Cartesian product, meaning each row from each table is matched with each row from ll other tables. Such a query as you request would produce for 10 tables with 10 records each no less than 10e10 records, ie. 100 billion records. I'm sure you don't want this.
Perhaps if you explain what you what to achieve, not how, we can help better.
To select * from each table, one after another, you can use the undocumented but well known sp_msforeachtable:
sp_msforeachtable 'select * from ?'
If you are going to send to Excel, I would suggest you use the export wizard and simply select all the tables there. In the object browser, put your cursor on the database name and right click. Chose Tasks - Export Data and follow the wizard. WHy anyone would want an entire database in Excel is beyond me, but that's the best way. If you need to do it more than once you can save the export in an SSIS package.
In SQL Server 2016 Management Studio ( Version: 13.0.15900.1), to get all column names in a specified table, below is the syntax:
**Select name from [YourDatabaseName].[sys].[all_columns]
where object_id=(Select object_id from [YourDatabaseName].[sys].[tables]
where name='YourTableName')**