Get column names of all tables in SQL [duplicate] - sql

This question already has answers here:
Getting list of tables, and fields in each, in a database
(13 answers)
Closed 3 years ago.
I need a query to generate column names (and it's type if possible) of all tables in database.
Is there any simple way?

You can use INFORMATION_SCHEMA.COLUMNS:
select c.*
from INFORMATION_SCHEMA.COLUMNS c;
This has name, type, and a lot of other information for all tables in a database -- note, not on a server but in a database.

You can use INFORMATION_SCHEMA.COLUMNS to list the columns of a given table.
create table tbl1 (id int)
Select * from INFORMATION_SCHEMA.COLUMNS where table_name in ('tbl1')
Demo
You can also use sys.columns as shown below
SELECT TAB.name AS TableName
,TAB.object_id AS ObjectID
,COL.name AS ColumnName
,COL.user_type_id AS DataTypeID
FROM sys.columns COL
INNER JOIN sys.tables TAB ON COL.object_id = TAB.object_id
-- where TAB.name = '<TABLENAME>'
-- Uncomment above line and add <Table Name> to fetch details for particular table
-- where COL.name = '<COLUMNNAME>'
-- Uncomment above line and add <Column Name> to fetch details for particular column names
Demo of sys.columns.
For the complete information of different types of result for a given table i.e., column name, data type and there size you can refer this reference.
Hope it will help you.

Related

How to update column name after finding the table names from information schema

I have run a script to find the table names with a specific column name from a database using the information schema
here is the query
use IMS_SCMS_DIGITAL_POWER
select * from information_schema.columns
where column_name like 'COMPANY_ID%'
after finding the table names now i would like to update the specific column values of all the database. Need solutions.
Run following query to get all tablenames with specific column name
SELECT t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%COMPANY_ID%'
just use in forward only cursor with tablenames to update the specific table.

Searching for a table based on values contained in the table

I have a table with a reason_id foreign key. I need to map that back to its primary table. I have searched our databases for matching/similar column names but I wasn't able to find the table.
I have a list of values that would be associated with the reason_id. I'd like to search for tables that contain the list I have. Any help would be appreciated.
Here's the query I was running to search for columns:
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
c.name like '%reason%'
There is no easy way to find the related data in other tables.
I'd try with tools such as ApexSQL Search or SQL Search. Both are free and you won’t go wrong with any of these.
If you want to do it with SQL only then identify all columns in all tables that have the same data type. To do so use sys.columns, sys.types and sys.tables views. Once you find all columns just try start writing queries for each table until you find the right one.
I’d go with something like this
select COUNT(*)
from tableX
where tableX.matchedColumn in
(
-- take 100 or more random rows from the original table
-- if result gives you a number that is near to the number of values listed here then you are most probably on the right track
)

Compare 2 different tables columns from 2 different databases

I have a requirement to compare different tables' columns from 2 different databases, in order to add columns to the master tables based on the requirement.
For example:
Assume in master database I have created one table like:
create table test(id int,name varchar(10))
Assume in test database I have created one table like
create table testings(id int,name varchar(20), sal int)
now I have to compare 2 table columns
I don't want to use red-gate tools.
Can anyone help me?
Is it just red-gate tools you don’t want to use or basically any third party tool? Why not, even if you don’t have the budget to buy you can still use this in trial mode to get the job done?
We’ve been using Apex Diff tool but there are many more out there.
With so many tools available you can probably run all one by one in trial mode for months…
Knowing system tables and how to do this natively is great but it’s just too time consuming...
You can use the EXCEPT or INTERSECT set operators for this. Like so:
SELECT id, name FROM master.dbo.test
EXCEPT -- or INTERSECT
SELECT id, name FROM test.dbo.testings
This will give you:
EXCEPT: returns any distinct values from the left query that are not
also found on the right query.
INTERSECT: returns any distinct values that are returned by both the
query on the left and right sides of the INTERSECT operand.
In your case, since you want to select from two different databases, you have to use a fully qualified table names. They have to be in the form database.schema.object_name.
Update: If you want compare the two tables columns' names, not the data itself, you have to work with the metadata tables to compare the columns' names the same way with EXCEPT.
For instance, suppose you have two databases:
Test database contains the table:
create table test(id int, name varchar(10), dep varchar(50));
and another database:
anotherdatabase database contains the table:
create table testings(id int,name varchar(20), sal int);
And you want to compare the two tables' columns and get the tables that don't exist in the other table, in our example you need to get sal and dep.
Then you can do this:
SELECT ColumnName
FROM
(
SELECT c.name "ColumnName"
FROM test.sys.tables t
INNER JOIN test.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN test.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'test'
EXCEPT
SELECT c.name
FROM anotherdatabase.sys.tables t
INNER JOIN anotherdatabase.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN anotherdatabase.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'testings'
) t1
UNION ALL
SELECT ColumnName
FROM
(
SELECT c.name ColumnName
FROM anotherdatabase.sys.tables t
INNER JOIN anotherdatabase.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN anotherdatabase.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'testings'
EXCEPT
SELECT c.name
FROM test.sys.tables t
INNER JOIN test.sys.all_columns c
ON t.object_id = c.object_id
INNER JOIN test.sys.types ty
ON c.system_type_id = ty.system_type_id
WHERE t.name = 'test'
) t2;
This should give you:
Note that: I joined the tables:
databasename.sys.tables, and
databasename.sys.all_columns
with the table:
databasename.systypes
to get only those columns that have the same data type. If you didn't joined this table, then if two columns have the same name but different data type, they would be the same.
To compare columns use INFORMATION_SCHEMA.COLUMNS table in a SQL SERVER.
This is the exmaple:
select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='your_table_name1'
except
select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='your_table_name2'
This is a GPL Java program I wrote for comparing data in any two tables, with a common key and common columns, across any two heterogeneous databases using JDBC: https://sourceforge.net/projects/metaqa/
It intelligently forgives (numeric, string and date) data type differences by reducing them to a common format. The output is a sparse tab delimited file with .xls extension for use in a spreadsheet.

Copy Column Into Existing Table using SQL

I want to create a column in databaseA with the same name, type, length and precision as another column in databaseB.
I need something like this:
INSERT INTO dbo.databaseA(col_name)
SELECT col_name
FROM dbo.databaseB;
GO
But the *col_name* does not yet exist in databaseA. I want to create it with the same type as *col_name* in databaseB.
I've also looked at:
ALTER TABLE table_name ADD col_name data_type
INSERT INTO dbo.databaseA(col_name)
SELECT col_name
FROM dbo.databaseB;
GO
But I don't know the data_type of the column I need to copy.
Edit:
** I'm using SQL Server 2008 R2 **
You can retrieve the datatype of the column from the database by querying the system views, similar to the following:
SELECT c.*, s.name
FROM sys.columns c
INNER JOIN sys.objects o
ON c.object_id = o.object_id
INNER JOIN sys.types s
ON c.user_type_id = s.user_type_id
WHERE o.name = 'B'
AND c.name = 'ColumnName'
You'll need to connect to DatabaseB, replace o.name = 'B' with your table's name and replace c.Name = 'ColumnName' with your column's name.
Once you have the datatype you would need to construct a DDL statement to add the column to the table in database A, something along the lines of the following:
ALTER TABLE dbo.MyTableName ADD MyColumnName DATA_TYPE_HERE
Once the table has been updated you can construct and execute your insert statement:
INSERT INTO DatabaseA.dbo.MyTableName (column list)
SELECT (column list)
FROM DatabaseB.dbo.MyTableName
Note that the above assumes both databases are located on the same SQL Server Instance and they both reside in the dbo schema.
If this is something you plan on using in the future you should add some defensive programming steps to make sure you only add the column if the column doesn't already exist in the table.

Dynamically determining table name given field name in SQL server

Strange situation: I am trying to remove some hard coding from my code. There is a situation where I have a field, lets say "CityID", and using this information, I want to find out which table contains a primary key called CityID.
Logically, you'd say that it's probably a table called "City" but it's not... that table is called "Cities". There are some other inconsistencies in database naming hence I can never be sure if removing the string "ID" and finding out the plural will be sufficient.
Note: Once I figure out that CityID refers to a table called Cities, I will perform a join to replace CityID with city name on the fly. I will appreciate if someonw can also tell me how to find out the first varchar field in a table given its name.
SELECT name FROM sysobjects
WHERE id IN ( SELECT id FROM syscolumns WHERE name = 'THE_COLUMN_NAME' )
To get column information from the specified table:
SELECT column_name, data_type, character_maximum_length
FROM information_schema.columns
WHERE table_name = 'myTable'
select table_name from information_schema.columns where column_name='CityID'
You can use the INFORMATION_SCHEMA tables to read metadata about the database.
SELECT
TABLE_NAME
FROM
[db].[INFORMATION_SCHEMA].[COLUMNS]
WHERE
COLUMN_NAME='CityID';
For a primer in what's in the INFORMAITON_SCHEMA, see INFORMATION_SCHEMA, a map to your database
The information you seek is all available in the information schema views. Note that you will find many sources telling you how to directly query the underlying system tables that these are views onto - and I must admit that I do the same when it's just to find something out quickly - but the recommended way for applications is to go through these views.
For example, to find your CityID column:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'CityID'
To find the first varchar field in a table:
SELECT TOP 1 * FROM INFORMATION_SCHEMA.COLUMNS WHERE
TABLE_NAME = 'TableName'
AND DATA_TYPE = 'varchar' -- This is off the top of my head!
ORDER BY ORDINAL_POSITION
As I understand from your question, you want to find tables which contain CITYID column in primary key
You can use SQL Server system views like sysindexes and sysindexkeys as shown in SQL tutorial to query database table primary keys including composite primary keys which are formed
SELECT
TBL.name as TableName
FROM sysobjects as PK
INNER JOIN sys.objects as TBL
on TBL.object_id = PK.parent_obj
INNER JOIN sysindexes as IND
on IND.name = PK.name AND
IND.id = TBL.object_id
INNER JOIN SysIndexKeys as KEYS
on KEYS.id = IND.id AND
KEYS.indid = IND.indid
INNER JOIN syscolumns as COL
on COL.id = KEYS.id AND
COL.colid = KEYS.colid
WHERE
PK.xtype = 'PK' AND
COL.name = 'CityID'