Is there a SQL statement that can return the type of a column in a table?
-
7Depends on the RDBMS; SQL Server has the `sys.syscolumns` table for example. – LittleBobbyTables - Au Revoir Nov 15 '12 at 20:25
-
5Yes, but it'll be different depending on what type of RDBMS you're using - SQL is a language, not the database product, and this question relies on the specific product. You'll be able to find this sort of information in the `INFORMATION_SCHEMA.COLUMNS` table - if your RDBMS has it. – Bridge Nov 15 '12 at 20:27
30 Answers
- In ISO SQL (i.e. most RDBMS today) you can use the
INFORMATION_SCHEMA.COLUMNS
view, which SQL Server supports.- This view's
DATA_TYPE
column contains the T-SQL/SQL Server type names, except that it doesn't include arguments for parameterised types, which can result in unexpected/unintentional column behaviour.- For example, given three columns typed as
nvarchar(max)
,datetime2(3)
, anddecimal(10,5)
then the output will benvarchar
,datetime2
, anddecimal
respectively.- This is a problem because a column typed as
nvarchar
(without(max)
or(123)
) is the same asnvarchar(1)
, and usingdecimal
is the same asdecimal(18,0)
which cannot store non-integer values.
- This is a problem because a column typed as
- The solution is to also look at
CHARACTER_OCTET_LENGTH
(forbinary
),CHARACTER_MAXIMUM_LENGTH
(forchar
andnchar
),DATETIME_PRECISION
(fordatetime2
anddatetimeoffset
), andNUMERIC_PRECISION
withNUMERIC_SCALE
(fordecimal
andnumeric
) in order to reconstruct the type's parameter values.- Note that
float(n)
can be ignored as SQL Server only supportsfloat(24)
andfloat(53)
which are aliased byreal
andfloat
respectively in theDATA_TYPE
column.
- Note that
- For example, given three columns typed as
- This view's
WITH q AS (
SELECT
c.TABLE_SCHEMA,
c.TABLE_NAME,
c.ORDINAL_POSITION,
c.COLUMN_NAME,
c.DATA_TYPE,
CASE
WHEN c.DATA_TYPE IN ( N'binary', N'varbinary' ) THEN ( CASE c.CHARACTER_OCTET_LENGTH WHEN -1 THEN N'(max)' ELSE CONCAT( N'(', c.CHARACTER_OCTET_LENGTH , N')' ) END )
WHEN c.DATA_TYPE IN ( N'char', N'varchar', N'nchar', N'nvarchar' ) THEN ( CASE c.CHARACTER_MAXIMUM_LENGTH WHEN -1 THEN N'(max)' ELSE CONCAT( N'(', c.CHARACTER_MAXIMUM_LENGTH, N')' ) END )
WHEN c.DATA_TYPE IN ( N'datetime2', N'datetimeoffset' ) THEN CONCAT( N'(', c.DATETIME_PRECISION, N')' )
WHEN c.DATA_TYPE IN ( N'decimal', N'numeric' ) THEN CONCAT( N'(', c.NUMERIC_PRECISION , N',', c.NUMERIC_SCALE, N')' )
END AS DATA_TYPE_PARAMETER,
CASE c.IS_NULLABLE
WHEN N'NO' THEN N' NOT NULL'
WHEN N'YES' THEN N' NULL'
END AS IS_NULLABLE2
FROM
INFORMATION_SCHEMA.COLUMNS AS c
)
SELECT
q.TABLE_SCHEMA,
q.TABLE_NAME,
q.ORDINAL_POSITION,
q.COLUMN_NAME,
CONCAT( q.DATA_TYPE, ISNULL( q.DATA_TYPE_PARAMETER, N'' ), q.IS_NULLABLE2 ) AS FULL_DATA_TYPE
FROM
q
WHERE
q.TABLE_SCHEMA = 'yourSchemaName' AND
q.TABLE_NAME = 'yourTableName' AND
q.COLUMN_NAME = 'yourColumnName'
ORDER BY
q.TABLE_SCHEMA,
q.TABLE_NAME,
q.ORDINAL_POSITION;
Gives results like this:
-
20Only if you don't want to see the corresponding column name. This will only return the types. If you want to see the column name the type belongs to you will need to select COLUMN_NAME also... – HackyStack Nov 16 '12 at 13:47
-
12And if your table isn't in the default schema you could extend the condition with `AND TABLE_SCHEMA = 'yourSchema'` – luviktor Jun 05 '15 at 07:54
-
14this is great - but is it possible to also have it return the range for column's type? i.e. `varchar(255)` instead of `varchar` and `int(11)` instead of `int` ? – Don Cheadle Jun 29 '15 at 18:00
-
21@mmcrae : It is possible using column `CHARACTER_MAXIMUM_LENGTH` in `INFORMATION_SCHEMA.COLUMNS`. Just do a `SELECT * FROM INFORMATION_SCHEMA.COLUMNS` to see all the columns available. – Francis P Jul 08 '15 at 12:59
-
3
-
2@Ilya_Gazman In what context would you need to identify the type of a temp table column? – Francis P Jan 31 '17 at 13:20
-
3It would be useful to see full readable column type like `"numeric(10, 2)"` or `"varchar(100)"` – Evgeny Nozdrev Oct 31 '18 at 10:34
-
3You can use this on a view just by using the view name instead of the table name. I almost dismissed this answer for views until I thought of that. – donL Mar 11 '19 at 16:59
-
1How to use it in `IF` statement? For example I only want to do some logic if it's an `Integer`? – Pomme De Terre Apr 23 '19 at 12:21
-
1@FrancisP I suppose you might if you've created it using the `SELECT ... INTO` syntax and want to check what types SQL Server has decided to use behind the scenes. – Stewart Feb 04 '20 at 10:04
-
1If the DATA_TYPE is set for a particular column in table and we want to get all possible values of that column. SQL statement to get that? – Shubhank Gupta Nov 25 '21 at 07:36
-
1@PommeDeTerre: This works for me in an IF statement `IF ((SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'ACCOUNT' AND COLUMN_NAME = N'DESCRIPTION') = N'varchar') BEGIN PRINT 'TEST PASS'; END` – Ozair Kafray Feb 25 '22 at 12:50
-
Very useful. Just for beginners, don't forget that it should be single quote. Double quote raised a error for me (I am calling from Rstudio, R 4.1.2, using JDBC and DBI with Postgres driver) – Corina Roca Dec 16 '22 at 12:32
The easiest way in TSQL is:
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'

- 64,563
- 18
- 145
- 216

- 4,887
- 3
- 22
- 28
For SQL Server, this system stored procedure will return all table information, including column datatypes:
exec sp_help YOURTABLENAME

- 16,268
- 7
- 50
- 64

- 651
- 5
- 2
-
7I upvoted as this is although not exactely the answer but provides valuable information to me. E.g. the "IsComputed" information I didn't find in the Information schema but I can find in the sp_help procedure code and copy from there. – Christoph Sep 21 '15 at 08:48
-
7
-
4to clarifiy: the table or view name has to be selected in the editor and then press`Alt+F1`. Not in the solution Object Explorer. This is such a helpful feature – bugybunny May 07 '19 at 06:32
-
1And not only tables, also working OK on Views, just: 1. Connect to SQL Server in SSMS 2. Open New Query Window 3. Select your database: use
4. Run command: exec sp_help – Don G. Jul 19 '20 at 16:49 -
1https://stackoverflow.com/a/73442049/3934886 this syntax worked for me >> EXEC [ServerName].[DatabaseName].dbo.sp_help 'TableName'. – alex351 Aug 22 '22 at 11:16
If you're using MySQL you could try
SHOW COLUMNS FROM `tbl_name`;
Otherwise you should be able to do
DESCRIBE `tbl_name`;

- 558
- 4
- 8
-
2
-
4Yes. The `DESCRIBE` syntax is valid in Oracle as well, however MsSQL will not accept this syntax. – fimas Nov 15 '12 at 20:43
-
1
-
1
-
1I find DESC OR DESCRIBE (depending on the DBMS you use) useful for small tables with 3 or 4 columns then it shows the table structure with column name Nullable flag and column type for big tables however it take more time to return a result and it is harder to find the information your need. – velocity Jul 03 '18 at 11:09
In TSQL/MSSQL it looks like:
SELECT t.name, c.name
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types y ON y.user_type_id = c.user_type_id
WHERE t.name = ''
-
4Actually it is `JOIN sys.types y ON y.user_type_id = c.user_type_id` system_type_id is not unique. [sys.columns doc](https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-columns-transact-sql?view=sql-server-2017) – Fabricio May 18 '18 at 11:26
To build on the answers above, it's often useful to get the column data type in the same format that you need to declare columns.
For example, varchar(50)
, varchar(max)
, decimal(p, s)
.
This allows you to do that:
SELECT
[Name] = c.[name]
, [Type] =
CASE
WHEN tp.[name] IN ('varchar', 'char', 'varbinary') THEN tp.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length AS VARCHAR(25))) + ')'
WHEN tp.[name] IN ('nvarchar','nchar') THEN tp.[name] + '(' + IIF(c.max_length = -1, 'max', CAST(c.max_length / 2 AS VARCHAR(25)))+ ')'
WHEN tp.[name] IN ('decimal', 'numeric') THEN tp.[name] + '(' + CAST(c.[precision] AS VARCHAR(25)) + ', ' + CAST(c.[scale] AS VARCHAR(25)) + ')'
WHEN tp.[name] IN ('datetime2') THEN tp.[name] + '(' + CAST(c.[scale] AS VARCHAR(25)) + ')'
ELSE tp.[name]
END
, [RawType] = tp.[name]
, [MaxLength] = c.max_length
, [Precision] = c.[precision]
, [Scale] = c.scale
, [IsNullable] = c.is_nullable
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types tp ON c.user_type_id = tp.user_type_id
WHERE s.[name] = 'dbo' AND t.[name] = 'MyTable'

- 12,139
- 19
- 64
- 95
-
5This should have been the accepted answer. Thanks, maybe you can add the condition ( t.type = 'U' )--remove system table – Iannick Apr 09 '20 at 13:20
-
2And VARBINARY types could easily be catered for by adding that to the first `WHEN` line: `WHEN tp.[name] IN ('varchar', 'char', 'varbinary') THEN...` – Reversed Engineer Jun 18 '20 at 09:47
-
2The best answer, I would also add: `, [IsNullable] = c.is_nullable` right after `c.scale`. I think it's very useful. – SeReGa Aug 17 '22 at 19:36
-
Added varbinary and isnullable. @Iannick I'm not clear why type = 'U' is necessary? Is it even possible to have a system table with the same name and schema as a user table? – MgSam Sep 29 '22 at 13:19
in oracle SQL you would do this:
SELECT
DATA_TYPE
FROM
all_tab_columns
WHERE
table_name = 'TABLE NAME' -- in uppercase
AND column_name = 'COLUMN NAME' -- in uppercase

- 1,352
- 10
- 19
Another variation using MS SQL:
SELECT TYPE_NAME(system_type_id)
FROM sys.columns
WHERE name = 'column_name'
AND [object_id] = OBJECT_ID('[dbo].[table_name]');

- 2,963
- 1
- 27
- 34
Using TSQL/MSSQL
This query will get you: table name, column name, data type, data type length, and allowable nulls
SELECT TABLE_NAME,COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'your_table_name'
The only thing that needs to be changed is your_table_name.

- 1,091
- 11
- 13
This also works as it selects just the column names and their respective character type
SELECT COLUMN_NAME ,DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Items';

- 277
- 3
- 7
To retrieve the actual declared data types, for example for use in dynamic SQL to ALTER COLUMNs, something like this can be used:
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE
+ CASE WHEN DATA_TYPE IN ('char','nchar','varchar','nvarchar','binary','varbinary')
AND CHARACTER_MAXIMUM_LENGTH > 0 THEN
COALESCE('('+CONVERT(varchar,CHARACTER_MAXIMUM_LENGTH)+')','')
ELSE '' END
+ CASE WHEN DATA_TYPE IN ('decimal','numeric') THEN
COALESCE('('+CONVERT(varchar,NUMERIC_PRECISION)+','+CONVERT(varchar,NUMERIC_SCALE)+')','')
ELSE '' END
AS Declaration_Type,
CASE WHEN IS_NULLABLE='NO' THEN 'NOT ' ELSE '' END + 'NULL' AS Nullable
FROM INFORMATION_SCHEMA.COLUMNS
ORDER BY 1,2

- 5,799
- 4
- 34
- 30
From SQL Server 2012 on:
SELECT * FROM sys.dm_exec_describe_first_result_set( N'SELECT * FROM [my].[Table]', NULL, 0 );

- 61
- 1
- 2
USE [YourDatabaseName]
GO
SELECT column_name 'Column Name',
data_type 'Data Type'
FROM information_schema.columns
WHERE table_name = 'YourTableName'
GO
This will return the values Column Name, showing you the names of the columns, and the Data Types of those columns (ints, varchars, etc).

- 742
- 1
- 8
- 16
For IBM DB2 :
SELECT TYPENAME FROM SYSCAT.COLUMNS WHERE TABSCHEMA='your_schema_name' AND TABNAME='your_table_name' AND COLNAME='your_column_name'

- 143
- 7
Using TSQL/MSSQL
You can use INTO
keyword.
The result of SELECT
into a real TABLE
Example: select .... INTO real_table_name
After
sp_help real_table_name

- 5,818
- 5
- 42
- 58

- 41
- 1
Since some people were asking for the precision as well with the data type, I would like to share my script that I have created for such a purpose.
SELECT TABLE_NAME As 'TableName'
COLUMN_NAME As 'ColumnName'
CONCAT(DATA_TYPE, '(', COALESCE(CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, DATETIME_PRECISION, ''), IIF(NUMERIC_SCALE <> 0, CONCAT(', ', NUMERIC_SCALE), ''), ')', IIF(IS_NULLABLE = 'YES', ', null', ', not null')) As 'ColumnType'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE -- ...
ORDER BY 'TableName', 'ColumnName'
It's not perfect but it works in most cases.
Using Sql-Server

- 105
- 10
-
This answer's query returns incorrect results for `binary` and `varbinary` columns, as they use `CHARACTER_OCTET_LENGTH` instead of `CHARACTER_MAXIMUM_LENGTH`. – Dai Apr 13 '23 at 16:03
Another option for MS SQL is to replace the select
query here with the query you want the types for:
declare @sql varchar(4000);
set @sql = 'select ''hi'' as greeting';
select * from master.sys.dm_exec_describe_first_result_set (@sql, Null, 0);

- 2,775
- 7
- 20
- 26

- 51
- 1
Just if someone finds this useful. In SQL Server:
sp_columns 'yourtablename'
This will give details of all the columns. It gives you column_name, data_type, type_name, precision, length, iss_nullable, etc.

- 8,111
- 25
- 27
- 44
use this query
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TABLE_NAME'
ORDER BY ORDINAL_POSITION

- 131
- 1
- 5
Below SQL script working perfectly at my end.
SELECT column_name AS 'Column Name',data_type AS 'Data Type'
FROM information_schema.columns
WHERE table_name = '[Table Name]'

- 166
- 1
- 1
- 9
In my case I needed to get the data type for Dynamic SQL (Shudder!) anyway here is a function that I created that returns the full data type. For example instead of returning 'decimal' it would return DECIMAL(18,4): dbo.GetLiteralDataType

- 1
- 1

- 1,469
- 2
- 17
- 39
Use this query to get Schema, Table, Column,Type, max_length, is_nullable
SELECT QUOTENAME(SCHEMA_NAME(tb.[schema_id])) AS 'Schema'
,QUOTENAME(OBJECT_NAME(tb.[OBJECT_ID])) AS 'Table'
,C.NAME as 'Column'
,T.name AS 'Type'
,C.max_length
,C.is_nullable
FROM SYS.COLUMNS C INNER JOIN SYS.TABLES tb ON tb.[object_id] = C.[object_id]
INNER JOIN SYS.TYPES T ON C.system_type_id = T.user_type_id
WHERE tb.[is_ms_shipped] = 0
ORDER BY tb.[Name]

- 595
- 10
- 23
SHOW COLUMNS FROM //table_name// ;
It will give you information about all the columns from the table .

- 9,725
- 3
- 31
- 48

- 39
- 1
I find this useful for queries, especially if they use aggregates or several tables (SQL Server)
DECLARE @query nvarchar(max) = 'select * from yourtable';
EXEC sp_describe_first_result_set @query, null, 0;

- 31
- 4
I think the simplest and most useful way in Microsoft SQL Server Management Studio:
EXEC [ServerName].[DatabaseName].dbo.sp_help 'TableName'

- 1,826
- 1
- 21
- 32
For Apache Derby as shown in this answer:
select columndatatype from sys.syscolumns
where referenceid = (
select tableid from sys.systables
where tablename = 'YOUR_TABEL_NAME'
and columnname= 'YOUR_COLUMN_NAME')

- 4,722
- 6
- 37
- 58
In vb60 you can do this:
Public Cn As ADODB.Connection
'open connection
Dim Rs As ADODB.Recordset
Set Rs = Cn.OpenSchema(adSchemaColumns, Array(Empty, Empty, UCase("Table"), UCase("field")))
'and sample (valRs is my function for rs.fields("CHARACTER_MAXIMUM_LENGTH").value):
RT_Charactar_Maximum_Length = (ValRS(Rs, "CHARACTER_MAXIMUM_LENGTH"))
rt_Tipo = (ValRS(Rs, "DATA_TYPE"))

- 989
- 1
- 8
- 9
simply do this
describe table test.oim_test_2
you will get details for all your columns with their data types

- 1
- 1
can use below scrip to gett he same:
SELECT column_name 'Column_Name', data_type 'Data_Type'
FROM information_schema.columns
WHERE table_name = 'Name of your desired table'
Note: It will not return what size you've specified for varchar/nvarchar type column(s)
If want to get full details about a table then can use below script:
EXEC [Your Database Name].dbo.sp_help 'Your Table Name'

- 329
- 4
- 22