Declaración SQL para obtener el tipo de columna
¿Existe una declaración SQL que pueda devolver el tipo de columna en una tabla?
Aceptado
- En ISO SQL (es decir, la mayoría de los RDBMS actuales) puede utilizar la
INFORMATION_SCHEMA.COLUMNS
vista que admite SQL Server .- La columna de esta vista
DATA_TYPE
contiene los nombres de los tipos de T-SQL/SQL Server, excepto que no incluye argumentos para los tipos parametrizados, lo que puede dar lugar a un comportamiento inesperado o no intencionado de la columna.- Por ejemplo, dadas tres columnas escritas como
nvarchar(max)
,datetime2(3)
ydecimal(10,5)
, la salida seránvarchar
,datetime2
ydecimal
respectivamente.- Esto es un problema porque una columna escrita como
nvarchar
(sin(max)
o(123)
) es lo mismo quenvarchar(1)
y usandodecimal
es lo mismodecimal(18,0)
que no puede almacenar valores que no sean enteros .
- Esto es un problema porque una columna escrita como
- La solución es mirar también
CHARACTER_OCTET_LENGTH
(parabinary
),CHARACTER_MAXIMUM_LENGTH
(parachar
ynchar
),DATETIME_PRECISION
(paradatetime2
ydatetimeoffset
) yNUMERIC_PRECISION
conNUMERIC_SCALE
(paradecimal
ynumeric
) para reconstruir los valores de los parámetros del tipo.- Tenga en cuenta que
float(n)
se puede ignorar ya que SQL Server solo admitefloat(24)
yfloat(53)
que tienen el alias dereal
yfloat
respectivamente en laDATA_TYPE
columna.
- Tenga en cuenta que
- Por ejemplo, dadas tres columnas escritas como
- La columna de esta vista
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;
Da resultados como este:
La forma más sencilla en TSQL es:
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'