using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Xml.Serialization; namespace ServerExplorer.Code { [Serializable] public class TablaDesc { #region Data parameters private String _esquema = String.Empty; [XmlAttribute("Esquema")] public string Esquema { get { return _esquema; } set { _esquema = value; } } private String _nombre = String.Empty; [XmlAttribute("Nombre")] public string Nombre { get { return _nombre; } set { _nombre = value; } } private readonly List _columnas = new List(); [XmlArray("Columnas")] public List Columnas { get { return _columnas; } } #endregion #region FillDesc // Obtener una columna existente private ColumnaDesc GetCol(String nombre) { foreach (ColumnaDesc col in Columnas) { if (String.Compare(col.Nombre, nombre, StringComparison.Ordinal) == 0) { return (col); } } return null; } public void FillDesc(String esquema, String nombre, SqlConnection cnx) { // establecer esquema y nombre Esquema = esquema; Nombre = nombre; // Preparar comando y parametros var da = new SqlDataAdapter(@" SELECT col.COLUMN_NAME AS Columna, col.DATA_TYPE AS Tipo, col.CHARACTER_MAXIMUM_LENGTH AS Tamanho, c.CONSTRAINT_TYPE AS TipoClave, col.IS_NULLABLE AS Nullable FROM INFORMATION_SCHEMA.COLUMNS AS col LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS k ON col.COLUMN_NAME=k.COLUMN_NAME AND col.TABLE_NAME=k.TABLE_NAME AND col.TABLE_SCHEMA=k.TABLE_SCHEMA LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS c ON k.CONSTRAINT_NAME=c.CONSTRAINT_NAME WHERE col.TABLE_NAME=@nombreTabla AND col.TABLE_SCHEMA=@nombreEsquema ORDER BY col.ORDINAL_POSITION ", cnx); var prm = new SqlParameter("@nombreTabla", SqlDbType.VarChar, 100) {Value = nombre}; da.SelectCommand.Parameters.Add(prm); prm = new SqlParameter("@nombreEsquema", SqlDbType.VarChar, 100) {Value = esquema}; da.SelectCommand.Parameters.Add(prm); // Obtener datatable con las columnas var dt = new DataTable(); cnx.Open(); da.Fill(dt); cnx.Close(); // Recorrer datatable estableciendo la lista de columnas Columnas.Clear(); foreach (DataRow dr in dt.Rows) { // Obtener columna ColumnaDesc col = GetCol((String) dr["Columna"]); if (col == null) { col = new ColumnaDesc(); Columnas.Add(col); } // Establecer datos de la columna col.Nombre = (String) dr["Columna"]; col.Tipo = ((String) dr["Tipo"]).ToLower(); if (dr["Tamanho"] != DBNull.Value) { col.Tamanho = (int) dr["Tamanho"]; } if (dr["TipoClave"] != DBNull.Value) { if (((String) dr["TipoClave"]).Contains("PRIMARY")) { col.Primaria = true; } } string strNullable = ((String) dr["Nullable"]).ToLower(); col.Nullable = (strNullable == "yes"); } } #endregion } #region TipoCol public enum TipoCol { Unset, Numerico, AproxNumerico, Tiempo, Texto, Binario, Booleano, Otro } #endregion [Serializable] public class ColumnaDesc { #region Data properties private string _nombre = String.Empty; [XmlAttribute("Nombre")] public string Nombre { get { return _nombre; } set { _nombre = value; } } private string _tipo = String.Empty; [XmlAttribute("Tipo")] public string Tipo { get { return _tipo; } set { _tipo = value; } } private int _tamanho = -1; [XmlAttribute("Tamanho")] public int Tamanho { get { return _tamanho; } set { _tamanho = value; } } private bool _nullable; [XmlAttribute("Nullable")] public bool Nullable { get { return _nullable; } set { _nullable = value; } } private bool _primaria; [XmlAttribute("Primaria")] public bool Primaria { get { return _primaria; } set { _primaria = value; } } #endregion #region GetTipo private TipoCol _tipoCol = TipoCol.Unset; public TipoCol GetTipo() { string strTipo = Tipo.ToLower(); if (_tipoCol != TipoCol.Unset) { return _tipoCol; } // Numericos if ( strTipo == "bigint" || strTipo == "int" || strTipo == "smallint" || strTipo == "tinyint" || strTipo == "bigint" ) { _tipoCol = TipoCol.Numerico; } // Aproximados numericos if ( strTipo == "float" || strTipo == "real" ) { _tipoCol = TipoCol.AproxNumerico; } // Tiempo if ( strTipo == "date" || strTipo == "datetimeoffset" || strTipo == "datetime2" || strTipo == "smalldatetime" || strTipo == "datetime" || strTipo == "time" ) { _tipoCol = TipoCol.Tiempo; } // Texto if ( strTipo == "char" || strTipo == "varchar" || strTipo == "text" || strTipo == "nchar" || strTipo == "nvarchar" || strTipo == "ntext" ) { _tipoCol = TipoCol.Texto; } // Binario if ( strTipo == "binary" || strTipo == "varbinary" || strTipo == "image" ) { _tipoCol = TipoCol.Binario; } // Booleano if ( strTipo == "bit" ) { _tipoCol = TipoCol.Booleano; } // Otro _tipoCol = TipoCol.Otro; return _tipoCol; } #endregion } }