What is the equivalent of 'describe table' in SQL Server? - sql
I have a SQL Server database and I want to know what columns and types it has. I'd prefer to do this through a query rather than using a GUI like Enterprise Manager. Is there a way to do this?
You can use the sp_columns stored procedure:
exec sp_columns MyTable
There are a few methods to get metadata about a table:
EXEC sp_help tablename
Will return several result sets, describing the table, it's columns and constraints.
The INFORMATION_SCHEMA views will give you the information you want, though unfortunately you have to query the views and join them manually.
Just in case you don't want to use stored proc, here's a simple query version
select *
from information_schema.columns
where table_name = 'aspnet_Membership'
order by ordinal_position
You can use following: sp_help tablename
Example: sp_help Customer
OR Use Shortcut Keys
Select the desired table and press ALT+F1.
Example: Customer Press ALT+F1.
Use this Query
Select * From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'TABLENAME'
In addition to the ways shown in other answers, you can use
SELECT TOP 0 * FROM table_name
This will give you the name of each column with no results in them, and completes almost instantly with minimal overhead.
Please use the following sql query; this worked for my case.
select * FROM INFORMATION_SCHEMA.Columns where table_name = 'tablename';
Just select table and press Alt+F1,
it will show all the information about table like Column name, datatype, keys etc.
The SQL Server equivalent to Oracle's describe command is the stored proc sp_help
The describe command gives you the information about the column names, types, length, etc.
In SQL Server, let's say you want to describe a table 'mytable' in schema 'myschema' in the database 'mydb', you can do following:
USE mydb;
exec sp_help 'myschema.mytable';
I wrote an sql*plus DESC(RIBE) like select (displays the column comments, too) in t-sql:
USE YourDB
GO
DECLARE #objectName NVARCHAR(128) = 'YourTable';
SELECT
a.[NAME]
,a.[TYPE]
,a.[CHARSET]
,a.[COLLATION]
,a.[NULLABLE]
,a.[DEFAULT]
,b.[COMMENTS]
-- ,a.[ORDINAL_POSITION]
FROM
(
SELECT
COLUMN_NAME AS [NAME]
,CASE DATA_TYPE
WHEN 'char' THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
WHEN 'numeric' THEN DATA_TYPE + '(' + CAST(NUMERIC_PRECISION AS VARCHAR) + ', ' + CAST(NUMERIC_SCALE AS VARCHAR) + ')'
WHEN 'nvarchar' THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
WHEN 'varbinary' THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
WHEN 'varchar' THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + ')'
ELSE DATA_TYPE
END AS [TYPE]
,CHARACTER_SET_NAME AS [CHARSET]
,COLLATION_NAME AS [COLLATION]
,IS_NULLABLE AS [NULLABLE]
,COLUMN_DEFAULT AS [DEFAULT]
,ORDINAL_POSITION
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = #objectName
) a
FULL JOIN
(
SELECT
CAST(value AS NVARCHAR) AS [COMMENTS]
,CAST(objname AS NVARCHAR) AS [NAME]
FROM
::fn_listextendedproperty ('MS_Description', 'user', 'dbo', 'table', #objectName, 'column', default)
) b
ON a.NAME COLLATE YourCollation = b.NAME COLLATE YourCollation
ORDER BY
a.[ORDINAL_POSITION];
The above mentioned select can be used in a system marked stored procedure and it can be called from any database of your instance on a simple way:
USE master;
GO
IF OBJECT_ID('sp_desc', 'P') IS NOT NULL
DROP PROCEDURE sp_desc
GO
CREATE PROCEDURE sp_desc (
#tableName nvarchar(128)
) AS
BEGIN
DECLARE #dbName sysname;
DECLARE #schemaName sysname;
DECLARE #objectName sysname;
DECLARE #objectID int;
DECLARE #tmpTableName varchar(100);
DECLARE #sqlCmd nvarchar(4000);
SELECT #dbName = PARSENAME(#tableName, 3);
IF #dbName IS NULL SELECT #dbName = DB_NAME();
SELECT #schemaName = PARSENAME(#tableName, 2);
IF #schemaName IS NULL SELECT #schemaName = SCHEMA_NAME();
SELECT #objectName = PARSENAME(#tableName, 1);
IF #objectName IS NULL
BEGIN
PRINT 'Object is missing from your function call!';
RETURN;
END;
SELECT #objectID = OBJECT_ID(#dbName + '.' + #schemaName + '.' + #objectName);
IF #objectID IS NULL
BEGIN
PRINT 'Object [' + #dbName + '].[' + #schemaName + '].[' + #objectName + '] does not exist!';
RETURN;
END;
SELECT #tmpTableName = '#tmp_DESC_' + CAST(##SPID AS VARCHAR) + REPLACE(REPLACE(REPLACE(REPLACE(CAST(CONVERT(CHAR, GETDATE(), 121) AS VARCHAR), '-', ''), ' ', ''), ':', ''), '.', '');
--PRINT #tmpTableName;
SET #sqlCmd = '
USE ' + #dbName + '
CREATE TABLE ' + #tmpTableName + ' (
[NAME] nvarchar(128) NOT NULL
,[TYPE] varchar(50)
,[CHARSET] varchar(50)
,[COLLATION] varchar(50)
,[NULLABLE] varchar(3)
,[DEFAULT] nvarchar(4000)
,[COMMENTS] nvarchar(3750));
INSERT INTO ' + #tmpTableName + '
SELECT
a.[NAME]
,a.[TYPE]
,a.[CHARSET]
,a.[COLLATION]
,a.[NULLABLE]
,a.[DEFAULT]
,b.[COMMENTS]
FROM
(
SELECT
COLUMN_NAME AS [NAME]
,CASE DATA_TYPE
WHEN ''char'' THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
WHEN ''numeric'' THEN DATA_TYPE + ''('' + CAST(NUMERIC_PRECISION AS VARCHAR) + '', '' + CAST(NUMERIC_SCALE AS VARCHAR) + '')''
WHEN ''nvarchar'' THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
WHEN ''varbinary'' THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
WHEN ''varchar'' THEN DATA_TYPE + ''('' + CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR) + '')''
ELSE DATA_TYPE
END AS [TYPE]
,CHARACTER_SET_NAME AS [CHARSET]
,COLLATION_NAME AS [COLLATION]
,IS_NULLABLE AS [NULLABLE]
,COLUMN_DEFAULT AS [DEFAULT]
,ORDINAL_POSITION
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = ''' + #objectName + '''
) a
FULL JOIN
(
SELECT
CAST(value AS NVARCHAR) AS [COMMENTS]
,CAST(objname AS NVARCHAR) AS [NAME]
FROM
::fn_listextendedproperty (''MS_Description'', ''user'', ''' + #schemaName + ''', ''table'', ''' + #objectName + ''', ''column'', default)
) b
ON a.NAME COLLATE Hungarian_CI_AS = b.NAME COLLATE Hungarian_CI_AS
ORDER BY
a.[ORDINAL_POSITION];
SELECT * FROM ' + #tmpTableName + ';'
--PRINT #sqlCmd;
EXEC sp_executesql #sqlCmd;
RETURN;
END;
GO
EXEC sys.sp_MS_marksystemobject sp_desc
GO
To execute the procedure type:
EXEC sp_desc 'YourDB.YourSchema.YourTable';
If you want to get a description an object of the current database (and schema) simple type:
EXEC sp_desc 'YourTable';
As sp_desc is a system marked procedure, you can even leave the exec command, too (not recommended anyway):
sp_desc 'YourTable';
You can use the sp_help 'TableName'
try it:
EXEC [ServerName].[DatabaseName].dbo.sp_columns 'TableName'
and you can get some table structure information, such as:
TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME...
In addition to above questions, if we have table in DB like db_name.dbo.table_name, we may use following steps
Connect with DB
USE db_name;
Use EXEC sp_help and don't forget to put table name as 'dbo.tablename' if you have dbo as schema.
exec sp_help 'dbo.table_name'
This should work!
I tried this and it's working for me
exec sp_help TABLE_NAME
First connect to your DB,
use DB_name
Then
exec sp_help 'Production.Et_Issue'
here 'production' is the schema name. If you dont have a schema,
you may simply write sp_help table_name
The problem with those answers is that you're missing the key info.
While this is a bit messy this is a quick version I came up with to make sure it contains the same info the MySQL Describe displays.
Select SC.name AS 'Field', ISC.DATA_TYPE AS 'Type', ISC.CHARACTER_MAXIMUM_LENGTH AS 'Length', SC.IS_NULLABLE AS 'Null', I.is_primary_key AS 'Key', SC.is_identity AS 'Identity'
From sys.columns AS SC
LEFT JOIN sys.index_columns AS IC
ON IC.object_id = OBJECT_ID('dbo.Expenses') AND
IC.column_id = SC.column_id
LEFT JOIN sys.indexes AS I
ON I.object_id = OBJECT_ID('dbo.Expenses') AND
IC.index_id = I.index_id
LEFT JOIN information_schema.columns ISC
ON ISC.TABLE_NAME = 'Expenses'
AND ISC.COLUMN_NAME = SC.name
WHERE SC.object_id = OBJECT_ID('dbo.Expenses')
This is the code I use within the EntityFramework Reverse POCO Generator (available here)
Table SQL:
SELECT c.TABLE_SCHEMA AS SchemaName,
c.TABLE_NAME AS TableName,
t.TABLE_TYPE AS TableType,
c.ORDINAL_POSITION AS Ordinal,
c.COLUMN_NAME AS ColumnName,
CAST(CASE WHEN IS_NULLABLE = 'YES' THEN 1
ELSE 0
END AS BIT) AS IsNullable,
DATA_TYPE AS TypeName,
ISNULL(CHARACTER_MAXIMUM_LENGTH, 0) AS [MaxLength],
CAST(ISNULL(NUMERIC_PRECISION, 0) AS INT) AS [Precision],
ISNULL(COLUMN_DEFAULT, '') AS [Default],
CAST(ISNULL(DATETIME_PRECISION, 0) AS INT) AS DateTimePrecision,
ISNULL(NUMERIC_SCALE, 0) AS Scale,
CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') AS BIT) AS IsIdentity,
CAST(CASE WHEN COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') = 1 THEN 1
WHEN COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsComputed') = 1 THEN 1
WHEN DATA_TYPE = 'TIMESTAMP' THEN 1
ELSE 0
END AS BIT) AS IsStoreGenerated,
CAST(CASE WHEN pk.ORDINAL_POSITION IS NULL THEN 0
ELSE 1
END AS BIT) AS PrimaryKey,
ISNULL(pk.ORDINAL_POSITION, 0) PrimaryKeyOrdinal,
CAST(CASE WHEN fk.COLUMN_NAME IS NULL THEN 0
ELSE 1
END AS BIT) AS IsForeignKey
FROM INFORMATION_SCHEMA.COLUMNS c
LEFT OUTER JOIN (SELECT u.TABLE_SCHEMA,
u.TABLE_NAME,
u.COLUMN_NAME,
u.ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE u
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON u.TABLE_SCHEMA = tc.CONSTRAINT_SCHEMA
AND u.TABLE_NAME = tc.TABLE_NAME
AND u.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY') pk
ON c.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.COLUMN_NAME = pk.COLUMN_NAME
LEFT OUTER JOIN (SELECT DISTINCT
u.TABLE_SCHEMA,
u.TABLE_NAME,
u.COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE u
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON u.TABLE_SCHEMA = tc.CONSTRAINT_SCHEMA
AND u.TABLE_NAME = tc.TABLE_NAME
AND u.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY') fk
ON c.TABLE_SCHEMA = fk.TABLE_SCHEMA
AND c.TABLE_NAME = fk.TABLE_NAME
AND c.COLUMN_NAME = fk.COLUMN_NAME
INNER JOIN INFORMATION_SCHEMA.TABLES t
ON c.TABLE_SCHEMA = t.TABLE_SCHEMA
AND c.TABLE_NAME = t.TABLE_NAME
WHERE c.TABLE_NAME NOT IN ('EdmMetadata', '__MigrationHistory')
Foreign Key SQL:
SELECT FK.name AS FK_Table,
FkCol.name AS FK_Column,
PK.name AS PK_Table,
PkCol.name AS PK_Column,
OBJECT_NAME(f.object_id) AS Constraint_Name,
SCHEMA_NAME(FK.schema_id) AS fkSchema,
SCHEMA_NAME(PK.schema_id) AS pkSchema,
PkCol.name AS primarykey,
k.constraint_column_id AS ORDINAL_POSITION
FROM sys.objects AS PK
INNER JOIN sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS k
ON k.constraint_object_id = f.object_id
INNER JOIN sys.indexes AS i
ON f.referenced_object_id = i.object_id
AND f.key_index_id = i.index_id
ON PK.object_id = f.referenced_object_id
INNER JOIN sys.objects AS FK
ON f.parent_object_id = FK.object_id
INNER JOIN sys.columns AS PkCol
ON f.referenced_object_id = PkCol.object_id
AND k.referenced_column_id = PkCol.column_id
INNER JOIN sys.columns AS FkCol
ON f.parent_object_id = FkCol.object_id
AND k.parent_column_id = FkCol.column_id
ORDER BY FK_Table, FK_Column
Extended Properties:
SELECT s.name AS [schema],
t.name AS [table],
c.name AS [column],
value AS [property]
FROM sys.extended_properties AS ep
INNER JOIN sys.tables AS t
ON ep.major_id = t.object_id
INNER JOIN sys.schemas AS s
ON s.schema_id = t.schema_id
INNER JOIN sys.columns AS c
ON ep.major_id = c.object_id
AND ep.minor_id = c.column_id
WHERE class = 1
ORDER BY t.name
I like this format:
name DataType Collation Constraints PK FK Comment
id int NOT NULL IDENTITY PK Order Line Id
pid int NOT NULL tbl_orders Order Id
itemCode varchar(10) Latin1_General_CI_AS NOT NULL Product Code
So I have used this:
DECLARE #tname varchar(100) = 'yourTableName';
SELECT col.name,
CASE typ.name
WHEN 'nvarchar' THEN 'nvarchar('+CAST((col.max_length / 2) as varchar)+')'
WHEN 'varchar' THEN 'varchar('+CAST(col.max_length as varchar)+')'
WHEN 'char' THEN 'char('+CAST(col.max_length as varchar)+')'
WHEN 'nchar' THEN 'nchar('+CAST((col.max_length / 2) as varchar)+')'
WHEN 'binary' THEN 'binary('+CAST(col.max_length as varchar)+')'
WHEN 'varbinary' THEN 'varbinary('+CAST(col.max_length as varchar)+')'
WHEN 'numeric' THEN 'numeric('+CAST(col.precision as varchar)+(CASE WHEN col.scale = 0 THEN '' ELSE ','+CAST(col.scale as varchar) END) +')'
WHEN 'decimal' THEN 'decimal('+CAST(col.precision as varchar)+(CASE WHEN col.scale = 0 THEN '' ELSE ','+CAST(col.scale as varchar) END) +')'
ELSE typ.name
END DataType,
ISNULL(col.collation_name,'') Collation,
CASE WHEN col.is_nullable = 0 THEN 'NOT NULL ' ELSE '' END + CASE WHEN col.is_identity = 1 THEN 'IDENTITY' ELSE '' END Constraints,
ISNULL((SELECT 'PK'
FROM sys.key_constraints kc INNER JOIN
sys.tables tb ON tb.object_id = kc.parent_object_id INNER JOIN
sys.indexes si ON si.name = kc.name INNER JOIN
sys.index_columns sic ON sic.index_id = si.index_id AND sic.object_id = si.object_id
WHERE kc.type = 'PK'
AND tb.name = #tname
AND sic.column_id = col.column_id),'') PK,
ISNULL((SELECT (SELECT name FROM sys.tables st WHERE st.object_id = fkc.referenced_object_id)
FROM sys.foreign_key_columns fkc INNER JOIN
sys.columns c ON c.column_id = fkc.parent_column_id AND fkc.parent_object_id = c.object_id INNER JOIN
sys.tables t ON t.object_id = c.object_id
WHERE t.name = tab.name
AND c.name = col.name),'') FK,
ISNULL((SELECT value
FROM sys.extended_properties
WHERE major_id = tab.object_id
AND minor_id = col.column_id),'') Comment
FROM sys.columns col INNER JOIN
sys.tables tab ON tab.object_id = col.object_id INNER JOIN
sys.types typ ON typ.system_type_id = col.system_type_id
WHERE tab.name = #tname
AND typ.name != 'sysname'
ORDER BY col.column_id;
use
SELECT COL_LENGTH('tablename', 'colname')
None of other solution worked for me.
SELECT C.COLUMN_NAME, C.IS_NULLABLE, C.DATA_TYPE, TC.CONSTRAINT_TYPE, C.COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS AS C
FULL JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS CC ON C.COLUMN_NAME = CC.COLUMN_NAME
FULL JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC ON CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
WHERE C.TABLE_NAME = '<Table Name>';
Sample Output
If you are using FirstResponderKit from Brent Ozar team, you can run this query also:
exec sp_blitzindex #tablename='MyTable'
It will return all information about table:
indexes with their usage statistics(reads, writes, locks, etc), space
used and other
missing indexes
columns
foreign keys
statistics contents
Of course it's not a system and not so universal stp like sp_help or sp_columns, but it returns all possible information about your table and I think it's worth creating it at your environment and mentioning it here.
Just double click on the table name and press Alt+F1
CREATE PROCEDURE [dbo].[describe]
(
#SearchStr nvarchar(max)
)
AS
BEGIN
SELECT
CONCAT([COLUMN_NAME],' ',[DATA_TYPE],' ',[CHARACTER_MAXIMUM_LENGTH],' ',
(SELECT CASE [IS_NULLABLE] WHEN 'NO' THEN 'NOT NULL' ELSE 'NULL' END),
(SELECT CASE WHEN [COLUMN_DEFAULT] IS NULL THEN '' ELSE CONCAT(' DEFAULT ',[COLUMN_DEFAULT]) END)
) AS DESCRIPTION
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE #SearchStr
END
The query below will provide similar output as the info() function in python, Pandas library.
USE [Database_Name]
IF OBJECT_ID('tempdo.dob.#primary_key', 'U') IS NOT NULL DROP TABLE #primary_key
SELECT
CONS_T.TABLE_CATALOG,
CONS_T.TABLE_SCHEMA,
CONS_T.TABLE_NAME,
CONS_C.COLUMN_NAME,
CONS_T.CONSTRAINT_TYPE,
CONS_T.CONSTRAINT_NAME
INTO #primary_key
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS CONS_T
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS CONS_C ON CONS_C.CONSTRAINT_NAME= CONS_T.CONSTRAINT_NAME
SELECT
SMA.name AS [Schema Name],
ST.name AS [Table Name],
SC.column_id AS [Column Order],
SC.name AS [Column Name],
PKT.CONSTRAINT_TYPE,
PKT.CONSTRAINT_NAME,
SC.system_type_id,
STP.name AS [Data Type],
SC.max_length,
SC.precision,
SC.scale,
SC.is_nullable,
SC.is_masked
FROM sys.tables AS ST
JOIN sys.schemas AS SMA ON SMA.schema_id = ST.schema_id
JOIN sys.columns AS SC ON SC.object_id = ST.object_id
JOIN sys.types AS STP ON STP.system_type_id = SC.system_type_id
LEFT JOIN #primary_key AS PKT ON PKT.TABLE_SCHEMA = SMA.name
AND PKT.TABLE_NAME = ST.name
AND PKT.COLUMN_NAME = SC.name
ORDER BY ST.name ASC, SMA.name ASC
Related
Pass table name as parameter
I want to pass the table name as parameter and get all columns size of that table altered by column length + 50. alter PROCEDURE dbo.testsp #tablename varchar(100) AS BEGIN DECLARE #totalWeight TABLE (columnnames nvarchar(100)); INSERT INTO #totalWeight (columnnames) SELECT name FROM sys.columns WHERE object_id = object_id(#tablename); END GO
This query returns your alteration statements in the last column. You can then run them through dynamic sql. SELECT tbl.name 'Table Name', c.name 'Column Name', t.name, c.max_length 'Max Length in Bytes', c.precision , c.scale , c.is_nullable, q1.*, 'alter table [' +tbl.name +'] alter column [' +c.name +'] ' +t.name +'('+ convert(nvarchar(1000), CASE WHEN t.name IN ('nchar','nvarchar') THEN c.max_length/2 ELSE c.max_length END +50) +') ' + case c.is_nullable when 0 then ' not null' else ' null' end as 'Alteration statement' FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id inner join sys.tables tbl on tbl.object_id=c.object_id CROSS APPLY ( select t.name + CASE WHEN t.name IN ('char', 'varchar','nchar','nvarchar') THEN '('+ CASE WHEN c.max_length=-1 THEN 'MAX' ELSE CONVERT(VARCHAR(4), CASE WHEN t.name IN ('nchar','nvarchar') THEN c.max_length/2 ELSE c.max_length END ) END +')' WHEN t.name IN ('decimal','numeric') THEN '('+ CONVERT(VARCHAR(4),c.precision)+',' + CONVERT(VARCHAR(4),c.Scale)+')' ELSE '' END + case c.is_nullable when 0 then ' not null' else ' null' end as [DDL name before] )q1 where t.name IN ('char', 'varchar','nchar','nvarchar') and c.max_length>-1
Run the following example of query, it creates a bunch of ALTER statements. Copy-paste the result into a new query window and run it again. Add other data types from sys.types if need. SELECT 'ALTER TABLE [' + s.name + '].[' + t.name + '] ALTER COLUMN [' + c.name + '] ' + ty.name + '(' + CAST(c.max_length + 50 AS nvarchar(10)) + ') ' + CASE WHEN c.is_nullable = 1 THEN 'NULL' ELSE 'NOT NULL' END + ';' FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id INNER JOIN sys.schemas s ON t.schema_id = s.schema_id INNER JOIN sys.types ty ON c.system_type_id = ty.system_type_id WHERE t.type = 'U' AND c.system_type_id IN (167 /*varchar*/, 231 /*nvarchar*/)
SQL get table columns with type name
I have successfully getting the information of tables and columns from below query. Is there any handy way to get the type name with the description like nvarchar(20), numeric(14,2), varchar(max) etc. instead of lot's of CASE statements? SELECT o.name AS TableName, c.name AS ColumnName, t.name + CASE WHEN t.name LIKE '%char' THEN '(' + CASE WHEN c.max_length = -1 THEN 'max' ELSE CONVERT(varchar(10), c.max_length / CASE WHEN t.name LIKE 'n%' THEN 2 ELSE 1 END) END + ')' WHEN t.name IN ('numeric', 'decimal') THEN '(' + CONVERT(varchar(4), c.precision) + ',' + CONVERT(varchar(4), c.scale) + ')' -- WHEN .... many other types ELSE '' END AS TypeName FROM sys.objects o INNER JOIN sys.columns c ON o.object_id = c.object_id INNER JOIN sys.types t ON t.system_type_id = c.system_type_id AND t.user_type_id = c.user_type_id WHERE o.is_ms_shipped = 0 ORDER BY o.name, c.column_id Edit sp_help nor the information schema return the name not being like nvarchar(20), numeric(14,2), varchar(max)
I use this view to Document the Database.... you could used this and use the data_type and Length/Precision /****** Object: View [dbo].[vw_DataDictionary] Script Date: 17/07/2015 10:24:04 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER VIEW [dbo].[vw_DataDictionary] AS SELECT TOP (100) PERCENT tb.name AS Table_Name, CAST(ept.value AS nvarchar(200)) AS Table_Description, CAST(c.name AS nvarchar(200)) AS Column_Name, CAST(ep.value AS nvarchar(200)) AS column_Description, t.name AS data_type, c.is_nullable AS Is_Null, object_definition(c.default_object_id) AS default_text, c.max_length AS Length, c.precision AS numeric_precision, c.scale AS numeric_scale, c.column_id FROM sys.columns AS c LEFT OUTER JOIN sys.tables AS tb ON tb.object_id = c.object_id LEFT OUTER JOIN sys.types AS t ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id LEFT OUTER JOIN sys.extended_properties AS ept ON ept.major_id = tb.object_id AND ept.minor_id = 0 AND ept.name = 'MS_Description' LEFT OUTER JOIN sys.extended_properties AS ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' WHERE (tb.type = 'U') AND (tb.name <> 'sysdiagrams') ORDER BY Table_Name, c.column_id GO
For SQL Server 2008 R2, I have declared the type by CASE as below: SQL Fiddle SELECT DB_NAME() AS DatabaseName, SCHEMA_NAME(o.schema_id) AS SchemaName, o.name AS ObjectName, c.name AS ColumnName, RTRIM(o.type) AS ObjectType, t.name AS TypeName, c.max_length AS Length, -- The logic is implemented in this column t.name + CASE -- (max) for char type / binary only WHEN (t.name LIKE '%char%' OR t.name LIKE '%binary') AND c.max_length = -1 THEN '(max)' -- (n) where n = length / 2 for nchar and nvarchar WHEN t.name LIKE '%char%' AND LEFT(t.name, 1) = 'n' THEN '(' + CONVERT(varchar, c.max_length / 2) + ')' -- (n) where n = length WHEN t.name LIKE '%char%' OR t.name LIKE '%binary' THEN '(' + CONVERT(varchar, c.max_length) + ')' -- (p,s) where p = precision, s = scale WHEN t.name IN ('numeric', 'decimal') THEN '(' + CONVERT(varchar, c.precision) + ',' + CONVERT(varchar, c.scale) + ')' -- (s) where s = scale WHEN t.name IN ('time', 'datetime2', 'datetimeoffset') THEN '(' + CONVERT(varchar, c.scale) + ')' ELSE '' END AS Type FROM sys.objects o inner join sys.columns c on o.object_id = c.object_id inner join sys.types t on c.system_type_id = t.system_type_id and c.user_type_id = t.user_type_id WHERE 1 = 1 AND o.is_ms_shipped = 1
This should help you, Adopted from here DECLARE #tblname VARCHAR(300) SET #tblname = 'tblname' SELECT o.list AS ColumnsDescription FROM sysobjects so CROSS APPLY ( SELECT ' [' + column_name + '] ' + data_type + CASE data_type WHEN 'sql_variant' THEN '' WHEN 'text' THEN '' WHEN 'ntext' THEN '' WHEN 'xml' THEN '' WHEN 'decimal' THEN '(' + cast(numeric_precision AS VARCHAR) + ', ' + cast(numeric_scale AS VARCHAR) + ')' ELSE coalesce('(' + CASE WHEN character_maximum_length = - 1 THEN 'MAX' ELSE cast(character_maximum_length AS VARCHAR) END + ')', '') END + ' ' + CASE WHEN EXISTS ( SELECT id FROM syscolumns WHERE object_name(id) = so.NAME AND NAME = column_name AND columnproperty(id, NAME, 'IsIdentity') = 1 ) THEN 'IDENTITY(' + cast(ident_seed(so.NAME) AS VARCHAR) + ',' + cast(ident_incr(so.NAME) AS VARCHAR) + ')' ELSE '' END + ' ' + ( CASE WHEN IS_NULLABLE = 'No' THEN 'NOT ' ELSE '' END ) + 'NULL ' + CASE WHEN information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', ' FROM information_schema.columns WHERE table_name = so.NAME ORDER BY ordinal_position FOR XML PATH('') ) o(list) LEFT JOIN information_schema.table_constraints tc ON tc.Table_name = so.NAME AND tc.Constraint_Type = 'PRIMARY KEY' CROSS APPLY ( SELECT '[' + Column_Name + '], ' FROM information_schema.key_column_usage kcu WHERE kcu.Constraint_Name = tc.Constraint_Name ORDER BY ORDINAL_POSITION FOR XML PATH('') ) j(list) WHERE xtype = 'U' AND NAME = #tblname You can parse your results as you want.
SELECT COLUMN_NAME, CASE WHEN DATA_TYPE ='decimal' THEN DATA_TYPE+ '('+cast (NUMERIC_PRECISION as Varchar)+ ','+cast (NUMERIC_SCALE as Varchar)+ ')' WHEN CHARACTER_MAXIMUM_LENGTH is null THEN DATA_TYPE + cast ('' as Varchar) ELSE DATA_TYPE + '('+ cast (CHARACTER_MAXIMUM_LENGTH as Varchar)+')' END AS QuantityText FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'table_name' and TABLE_SCHEMA = 'dbo' order by COLUMN_NAME
How do I get constraints on a SQL Server table column
I have a column called MealType (VARCHAR) in my table with a CHECK constraint for {"Veg", "NonVeg", "Vegan"} That'll take care of insertion. I'd like to display these options for selection, but I couldn't figure out the SQL query to find out the constraints of a particular column in a table. From a first glance at system tables in SQL Server, it seems like I'll need to use SQL Server's API to get the info. I was hoping for a SQL query itself to get it.
Easiest and quickest way is to use: sp_help 'TableName'
This query should show you all the constraints on a table: select chk.definition from sys.check_constraints chk inner join sys.columns col on chk.parent_object_id = col.object_id inner join sys.tables st on chk.parent_object_id = st.object_id where st.name = 'Tablename' and col.column_id = chk.parent_column_id can replace the select statement with this: select substring(chk.Definition,2,3),substring(chk.Definition,9,6),substring(chk.Definition,20,5)
SELECT obj_table.NAME AS 'table', columns.NAME AS 'column', obj_Constraint.NAME AS 'constraint', obj_Constraint.type AS 'type' FROM sys.objects obj_table JOIN sys.objects obj_Constraint ON obj_table.object_id = obj_Constraint.parent_object_id JOIN sys.sysconstraints constraints ON constraints.constid = obj_Constraint.object_id JOIN sys.columns columns ON columns.object_id = obj_table.object_id AND columns.column_id = constraints.colid WHERE obj_table.NAME='table_name' ORDER BY 'table'
You can use sp_helpconstraint 'tableName', 'nomsg' to get all the constraints for the table. "sp_help" return far more information.
Thanks to orgtrigger for his example! I improved it to be able to remove unnecessary constraints (and then create their modified versions, if needed). Maybe this code will be useful for anybody. -- removing old constraints DECLARE #ConstraintNames TABLE (Name VARCHAR(MAX), RowNum INT) DECLARE #TableName VARCHAR(100) = 'HubSpot' INSERT #ConstraintNames SELECT [constraint].name, ROW_NUMBER() OVER (ORDER BY [constraint].[name]) AS RowNum FROM sys.default_constraints [constraint] INNER JOIN sys.columns col ON [constraint].parent_object_id = col.object_id INNER JOIN sys.tables st ON [constraint].parent_object_id = st.object_id WHERE st.name = #TableName AND col.name IN ('ForceUpdateOnImport', 'ForceUpdateOnExport') AND col.column_id = [constraint].parent_column_id SELECT * FROM #ConstraintNames DECLARE #i INT = 1, #count INT, #constraintName VARCHAR(MAX), #sql VARCHAR(MAX) SELECT #count = COUNT(1) FROM #ConstraintNames WHILE #i <= #count BEGIN SELECT #constraintName = cn.Name FROM #ConstraintNames cn WHERE cn.RowNum = #i SET #sql = 'ALTER TABLE ' + #TableName + ' DROP CONSTRAINT ' + #constraintName EXEC (#sql) SET #i = #i + 1 END
Below is helpful for check and default constraints. I use it for implicit constraints to offer up guidance for what the name should be. If you remove everything after the where clause, it should be good for any check/default constraints. SELECT /* obj_table.NAME AS 'table', columns.NAME AS 'column', obj_Constraint.NAME AS 'constraint', obj_Constraint.type AS 'type', sss.name as 'schema',*/ 'ALTER TABLE [' + ltrim(rtrim(sss.name))+'].['+ltrim(rtrim(obj_table.name)) + '] DROP CONSTRAINT [' + obj_Constraint.NAME + '];' As 'Wrong_Implicit_Constraint', 'ALTER TABLE [' + ltrim(rtrim(sss.name))+'].['+ltrim(rtrim(obj_table.name)) + '] ADD CONSTRAINT [' + CASE obj_Constraint.type WHEN 'D' THEN 'DF' WHEN 'F' THEN 'FK' WHEN 'U' THEN 'UX' WHEN 'PK' THEN 'PK' WHEN 'N' THEN 'NN' WHEN 'C' THEN 'CK' END + '_' + ltrim(rtrim(obj_table.name)) + '_' + columns.NAME + ']' + CASE obj_Constraint.type WHEN 'D' THEN ' DEFAULT (' + dc.definition +') FOR [' + columns.NAME + ']' WHEN 'C' THEN ' CHECK (' + cc.definition +')' ELSE '' END + ';' As 'Right_Explicit_Constraint' FROM sys.objects obj_table JOIN sys.objects obj_Constraint ON obj_table.object_id = obj_Constraint.parent_object_id JOIN sys.sysconstraints constraints ON constraints.constid = obj_Constraint.object_id JOIN sys.columns columns ON columns.object_id = obj_table.object_id AND columns.column_id = constraints.colid left join sys.schemas sss on obj_Constraint.schema_id=sss.schema_id left join sys.default_constraints dc on dc.object_id = obj_Constraint.object_id left join sys.check_constraints cc on cc.object_id = obj_Constraint.object_id WHERE obj_Constraint.type_desc LIKE '%CONSTRAINT' AND RIGHT(obj_Constraint.name,10) LIKE '[_][_]________' --match double underscore + 8 chars of anything AND RIGHT(obj_Constraint.name,8) LIKE '%[A-Z]%' --Ensure alpha in last 8 AND RIGHT(obj_Constraint.name,8) LIKE '%[0-9]%' --Ensure numeric in last 8 AND RIGHT(obj_Constraint.name,8) not LIKE '%[^0-9A-Z]%' --Ensure no special chars
How to find the database name and table name by using Column name
I need a query in Sql server 2005. I have a column name. Having that, I need to find a database name and table name. Is there any way to find it?
From SO's sister site, "StackExchange": https://dba.stackexchange.com/questions/511/how-to-list-search-all-columns-in-a-sql-server-2008-databases 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 '%EmployeeID%' ORDER BY schema_name, table_name;
Possible, this script will be helpful for you - DECLARE #SearchColumnName SYSNAME SELECT #SearchColumnName = 'EmployeeID' IF EXISTS( SELECT 1 FROM tempdb.dbo.sysobjects WHERE id = OBJECT_ID('tempdb.dbo.#DB') ) DROP TABLE #DB CREATE TABLE #DB ( [DB_NAME] SYSNAME , [OBJECT_NAME] SYSNAME , [COLUMN_NAME] SYSNAME ) DECLARE #SQL NVARCHAR(500) SELECT #SQL = 'USE [?] INSERT INTO #DB ( [DB_NAME] , [OBJECT_NAME] , [COLUMN_NAME] ) SELECT DB_NAME() , s.name + ''.'' + o.name , c.name FROM ( SELECT c.[object_id] , c.name FROM sys.columns c WITH (NOWAIT) WHERE c.name LIKE ''%'' + ''' + #SearchColumnName+ ''' + ''%'' ) c JOIN sys.objects o WITH (NOWAIT) ON c.[object_id] = o.[object_id] JOIN sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id] WHERE o.type = ''U''' EXEC sys.sp_MSforeachdb #SQL SELECT * FROM #DB ORDER BY [DB_NAME], [OBJECT_NAME]
Easiest Way To Diff Two Table Schemas In SQL Server 2008?
I have to do checks between a development and release database and do this manually, which is both slow and not 100% reliable (I only visually inspect the tables). Is there a quick and easy way to compare table schemas automatically? Maybe even a feature that does this built right into SQL server? Edit: I'm comparing structure only, thank you for pointing this out.
I'm a fan of SQL DBDiff, which is an open source tool you can use to compare tables, views, functions, users, etc. of two instances of SQL Server databases and generate a change script between the source and destination databases.
There are some commercial products that do this; Visual Studio 2010 Premium Edition can compare schemas. Some others: http://www.red-gate.com/products/SQL_Compare/index.htm http://www.apexsql.com/sql_tools_diff.aspx
Data or structure or both? Try RedGate sql compare or data compare. They both have free trials and are awesome. http://www.red-gate.com/products/SQL_Compare/index.htm http://www.red-gate.com/products/SQL_Data_Compare/index.htm
I'm a little late to the game...but this script I made has worked well for me. It'll work across linked servers too if needed. use master go DECLARE #Server1 VARCHAR(100) ='[CARNYSQLTEST1].'; --include a dot at the end DECLARE #DB1 VARCHAR(100) = '[ZipCrim]'; DECLARE #Table1 VARCHAR(100) = 'IntAction'; DECLARE #Server2 VARCHAR(100) ='[CARNYSQLDEV].'; --include a dot at the end DECLARE #DB2 VARCHAR(100) = '[ZipCrim]'; DECLARE #Table2 VARCHAR(100) = 'IntAction'; DECLARE #SQL NVARCHAR(MAX); SET #SQL = ' SELECT Table1.ServerName, Table1.DBName, Table1.SchemaName, Table1.TableName, Table1.ColumnName, Table1.name DataType, Table1.Length, Table1.Precision, Table1.Scale, Table1.Is_Identity, Table1.Is_Nullable, Table2.ServerName, Table2.DBName, Table2.SchemaName, Table2.TableName, Table2.ColumnName, Table2.name DataType, Table2.Length, Table2.Precision, Table2.Scale, Table2.Is_Identity, Table2.Is_Nullable FROM (SELECT ''' + #Server1 + ''' ServerName, ''' + #DB1 + ''' DbName, SCHEMA_NAME(t.schema_id) SchemaName, t.Name TableName, c.Name ColumnName, st.Name, c.Max_Length Length, c.Precision, c.Scale, c.Is_Identity, c.Is_Nullable FROM ' + #Server1 + #DB1 + '.sys.tables t INNER JOIN ' + #Server1 + #DB1 + '.sys.columns c ON t.Object_ID = c.Object_ID INNER JOIN sys.types st ON St.system_type_id = c.System_Type_id AND st.user_type_id = c.user_type_id WHERE t.Name = ''' + #Table1 + ''') Table1 FULL OUTER JOIN (SELECT ''' + #Server2 + ''' ServerName, ''' + #DB2 + ''' DbName, SCHEMA_NAME(t.schema_id) SchemaName, t.name TableName, c.name ColumnName, st.Name, c.max_length Length, c.Precision, c.Scale, c.Is_Identity, c.Is_Nullable FROM ' + #Server2 + #DB2 + '.sys.tables t INNER JOIN ' + #Server2 + #DB2 + '.sys.columns c ON t.Object_ID = c.Object_ID INNER JOIN sys.types st ON St.system_type_id = c.System_Type_id AND st.user_type_id = c.user_type_id WHERE t.Name = ''' + #Table2 + ''') Table2 ON Table1.ColumnName = Table2.ColumnName ORDER BY CASE WHEN Table1.ColumnName IS NULL THEN 2 ELSE 1 END, Table1.ColumnName ' EXEC sp_executesql #SQL
Soo, Googled this: for structures: see also: My previous answers' links doesn't work anymore for some reason, so here's another answer from TechNet: DECLARE #Sourcedb sysname DECLARE #Destdb sysname DECLARE #Tablename sysname DECLARE #SQL varchar(max) SELECT #Sourcedb = '<<SourceDatabaseName>>' SELECT #Destdb = '<<DestinationDatabaseName>>' SELECT #Tablename = '<<Tablename>>' -- '%' for all tables SELECT #SQL = ' SELECT Tablename = ISNULL(Source.tablename,Destination.tablename) ,ColumnName = ISNULL(Source.Columnname,Destination.Columnname) ,Source.Datatype ,Source.Length ,Source.precision ,Destination.Datatype ,Destination.Length ,Destination.precision ,[Column] = Case When Source.Columnname IS NULL then ''Column Missing in the Source'' When Destination.Columnname IS NULL then ''Column Missing in the Destination'' ELSE '''' end ,DataType = CASE WHEN Source.Columnname IS NOT NULL AND Destination.Columnname IS NOT NULL AND Source.Datatype <> Destination.Datatype THEN ''Data Type mismatch'' END ,Length = CASE WHEN Source.Columnname IS NOT NULL AND Destination.Columnname IS NOT NULL AND Source.Length <> Destination.Length THEN ''Length mismatch'' END ,Precision = CASE WHEN Source.Columnname IS NOT NULL AND Destination.Columnname IS NOT NULL AND Source.precision <> Destination.precision THEN ''precision mismatch'' END ,Collation = CASE WHEN Source.Columnname IS NOT NULL AND Destination.Columnname IS NOT NULL AND ISNULL(Source.collation_name,'''') <> ISNULL(Destination.collation_name,'''') THEN ''Collation mismatch'' END FROM ( SELECT Tablename = so.name , Columnname = sc.name , DataType = St.name , Length = Sc.max_length , precision = Sc.precision , collation_name = Sc.collation_name FROM ' + #Sourcedb + '.SYS.objects So JOIN ' + #Sourcedb + '.SYS.columns Sc ON So.object_id = Sc.object_id JOIN ' + #Sourcedb + '.SYS.types St ON Sc.system_type_id = St.system_type_id AND Sc.user_type_id = St.user_type_id WHERE SO.TYPE =''U'' AND SO.Name like ''' + #Tablename + ''' ) Source FULL OUTER JOIN ( SELECT Tablename = so.name , Columnname = sc.name , DataType = St.name , Length = Sc.max_length , precision = Sc.precision , collation_name = Sc.collation_name FROM ' + #Destdb + '.SYS.objects So JOIN ' + #Destdb + '.SYS.columns Sc ON So.object_id = Sc.object_id JOIN ' + #Destdb + '.SYS.types St ON Sc.system_type_id = St.system_type_id AND Sc.user_type_id = St.user_type_id WHERE SO.TYPE =''U'' AND SO.Name like ''' + #Tablename + ''' ) Destination ON source.tablename = Destination.Tablename AND source.Columnname = Destination.Columnname ' EXEC (#Sql)
For a free solution, you can use SQL Server Managements Objects to output the DDL script for each table, view, index, SP, UDF, etc. Then you can compare, either in code, or using a diff tool like WinMerge.
If two tables in same database, you can use this query select c2.table_name,c2.COLUMN_NAME from [INFORMATION_SCHEMA].[COLUMNS] c2 where table_name='table1' and c2.COLUMN_NAME not in (select column_name from [INFORMATION_SCHEMA].[COLUMNS] where table_name='table1')
you can take a look at http://cdttools.com/2011/10/sql-diff-erence/ its a low cost alternative, will walk schema between two databases and tell you whats changed. You can then use SQL Mgmt studio to generate "script->As Alter" to build change scripts. (caveat: I wrote it)
Modified a bit of BD.'s query, all credit goes to him. (Changed SCHEMA_NAME(schema_id) to sys.schemas join because SCHEMA_NAME(schema_id) works with current db context which is master, changed sorting and changed column names and added the status column) USE master GO DECLARE #Server1 VARCHAR(100) = 'Server1.', -- don't forget to include a dot at the end #Server2 VARCHAR(100) = 'Server2.', -- don't forget to include a dot at the end #DB1 VARCHAR(100) = 'Database1', #DB2 VARCHAR(100) = 'Database2' DECLARE #SQL NVARCHAR(MAX); SET #SQL = ' SELECT CASE WHEN s1.[Column] IS NOT NULL AND s2.[Column] IS NULL THEN ''New'' WHEN s1.[Column] IS NULL AND s2.[Column] IS NOT NULL THEN ''Deleted'' WHEN s1.[Column] IS NOT NULL AND s2.[Column] IS NOT NULL AND (s1.[Type] <> s2.[Type] OR s1.[Length] <> s2.[Length] OR s1.[Precision] <> s2.[Precision] OR s1.Scale <> s2.Scale OR s1.IsNullable <> s2.IsNullable OR s1.IsIdentity <> s2.IsIdentity OR s1.IdentitySeed <> s2.IdentitySeed OR s1.IdentityIncrement <> s2.IdentityIncrement OR s1.DefaultValue <> s2.DefaultValue) THEN ''Changed'' ELSE ''Identical'' END [Status], s1.[Database], s1.[Schema], s1.[Table], s1.[Column], s1.[Type], s1.IsCharType, s1.[Length], s1.[Precision], s1.Scale, s1.IsNullable, s1.IsIdentity, s1.IdentitySeed, s1.IdentityIncrement, s1.DefaultValue, s1.[Order], s2.[Database], s2.[Schema], s2.[Table], s2.[Column], s2.[Type], s2.IsCharType, s2.[Length], s2.[Precision], s2.Scale, s2.IsNullable, s2.IsIdentity, s2.IdentitySeed, s2.IdentityIncrement, s2.DefaultValue, s2.[Order] FROM ( SELECT ''' + #DB1 + ''' AS [Database], s.name AS [Schema], t.name AS [Table], c.name AS [Column], tp.name AS [Type], CASE WHEN tp.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharType, CASE WHEN c.max_length = -1 THEN ''MAX'' ELSE CAST(c.max_length AS VARCHAR(4)) END AS [Length], c.[precision], c.scale, c.is_nullable AS IsNullable, c.is_identity AS IsIdentity, CAST(ISNULL(ic.seed_value, 0) AS INT) AS IdentitySeed, CAST(ISNULL(ic.increment_value, 0) AS INT) AS IdentityIncrement, dc.definition AS DefaultValue, c.column_id AS [Order] FROM ' + #Server1 + #DB1 + '.sys.tables t INNER JOIN ' + #Server1 + #DB1 + '.sys.schemas s ON s.schema_id = t.schema_id INNER JOIN ' + #Server1 + #DB1 + '.sys.columns c ON c.object_id = t.object_id INNER JOIN ' + #Server1 + #DB1 + '.sys.types tp ON tp.system_type_id = c.system_type_id LEFT OUTER JOIN ' + #Server1 + #DB1 + '.sys.identity_columns ic ON ic.object_id = t.object_id AND ic.name = c.name LEFT OUTER JOIN ' + #Server1 + #DB1 + '.sys.default_constraints dc ON dc.object_id = c.default_object_id ) s1 FULL OUTER JOIN ( SELECT ''' + #DB2 + ''' AS [Database], s.name AS [Schema], t.name AS [Table], c.name AS [Column], tp.name AS [Type], CASE WHEN tp.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharType, CASE WHEN c.max_length = -1 THEN ''MAX'' ELSE CAST(c.max_length AS VARCHAR(4)) END AS [Length], c.[precision], c.scale, c.is_nullable AS IsNullable, c.is_identity AS IsIdentity, CAST(ISNULL(ic.seed_value, 0) AS INT) AS IdentitySeed, CAST(ISNULL(ic.increment_value, 0) AS INT) AS IdentityIncrement, dc.definition AS DefaultValue, c.column_id AS [Order] FROM ' + #Server2 + #DB2 + '.sys.tables t INNER JOIN ' + #Server2 + #DB2 + '.sys.schemas s ON s.schema_id = t.schema_id INNER JOIN ' + #Server2 + #DB2 + '.sys.columns c ON c.object_id = t.object_id INNER JOIN ' + #Server2 + #DB2 + '.sys.types tp ON tp.system_type_id = c.system_type_id LEFT OUTER JOIN ' + #Server2 + #DB2 + '.sys.identity_columns ic ON ic.object_id = t.object_id AND ic.name = c.name LEFT OUTER JOIN ' + #Server2 + #DB2 + '.sys.default_constraints dc ON dc.object_id = c.default_object_id ) s2 ON s2.[Schema] = s1.[Schema] AND s2.[Table] = s1.[Table] AND s2.[Column] = s1.[Column] ORDER BY CASE WHEN s1.[Database] IS NULL THEN s2.[Database] ELSE s1.[Database] END, CASE WHEN s1.[Schema] IS NULL THEN s2.[Schema] ELSE s1.[Schema] END, CASE WHEN s1.[Table] IS NULL THEN s2.[Table] ELSE s1.[Table] END, CASE WHEN s1.[Order] IS NULL THEN s2.[Order] ELSE s1.[Order] END ' EXEC sp_executesql #SQL
You can use the SQL Management studio tools to "Generate scripts" from both databases. Then use your favorite text comparison tool to see any differences. In the old days, this worked great, but in SQL 2005 the generate script code changed and the objects were no longer created in the same order, so the text comparison is less useful. I have not tested this in more recent versions of SQL so it may have been fixed. You can also try http://exportsqlscript.codeplex.com/ which I have used with good success to output the DDL as scripts for source code control and comparing versions. References: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=332400&wa=wsignin1.0 http://social.msdn.microsoft.com/Forums/en-US/sqltools/thread/505fd238-e0dc-42ae-8a54-2dceace81bb3/ http://exportsqlscript.codeplex.com/