Usando GetSchemaTable() para recuperar solo nombres de columna

¿Es posible usar GetSchemaTable() to retrieve only column names?

I have been trying to retrieve Column names (only) using this method, is it possible.

  DataTable table = myReader.GetSchemaTable();

  foreach (DataRow myField in table.Rows)
  {
      foreach (DataColumn myProperty in table.Columns)
      {
          fileconnectiongrid.Rows.Add(myProperty.ColumnName + " = " 
                            + myField[myProperty].ToString());
      }
  }

This code retrieves a lot of table data unwanted, I only need a list containing column names!:

preguntado el 28 de agosto de 12 a las 15:08

5 Respuestas

Tienes que usar ExecuteReader(CommandBehavior.SchemaOnly)):

DataTable schema = null;
using (var con = new SqlConnection(connection))
{
    using (var schemaCommand = new SqlCommand("SELECT * FROM table", con))
    {
        con.Open();
        using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly))
        {
            schema = reader.GetSchemaTable();
        }
    }
}

SchemaOnly:

The query returns column information only. When using SchemaOnly, the .NET Framework Data Provider for SQL Server precedes the statement being executed with SET FMTONLY ON.

The column name is in the first column of every row. I don't think that it's possible to omit the other column informations like ColumnOrdinal,ColumnSize,NumericPrecision and so on since you cannot use reader.GetString único propósito reader.GetSchemaTable en este caso.

But your loop is incorrect if you only want the column names:

foreach (DataRow col in schema.Rows)
{
    Console.WriteLine("ColumnName={0}", col.Field<String>("ColumnName"));
}

Respondido 28 ago 12, 15:08

Still returns all data :-( maybe something wrong with my loop. - user1495962

@user1495962: The column name is in the first column of every row. I don't think that it's possible to omit the other column informations like ColumnOrdinal,ColumnSize,NumericPrecision etc. Edited my answer - Tim Schmelter

Change your code to below if all you want is to display the column names. Your original code was trying to not only display column names, but also trying to display the actual data values as well.

DataTable table = myReader.GetSchemaTable();

foreach (DataRow myField in table.Rows)
{
    foreach (DataColumn myProperty in table.Columns)
    {
        fileconnectiongrid.Rows.Add(myProperty.ToString());
    }
}

Respondido 28 ago 12, 16:08

tr yid setting it with no luck - user1495962

This will give you all column names, you can place them in a string[] and do with them what you like.

foreach(var columnName in DataTable.Columns)
{
  Console.WriteLine(columnName);
}

Respondido el 27 de Septiembre de 13 a las 13:09

//Retrieve column schema into a DataTable.
schemaTable = reader.GetSchemaTable();

int index = schemaTable.Columns.IndexOf("ColumnName");
DataColumn columnName = schemaTable.Columns[index];

//For each field in the table...
foreach (DataRow myField in schemaTable.Rows)
  {
    String columnNameValue = myField[columnName].ToString();
    Console.WriteLine("ColumnName " + columnNameValue);
  }

Respondido 01 Jul 15, 18:07

I use same technics to add MAX-STRING-LENGTH restricción en personalizado TextBox in my VB.Net program.

I use a SQL SELECT command to get 4 column's values

    SELECT code_pays
          ,nom
          ,code_pays_short
          ,default_devise
      FROM pays
      ORDER BY nom

I use the result returned by an IDataReader object to fill a DataGridView.

And finally, I display each row's field in a Panel que contiene 4 TextBox.

To avoid that SQL UPDATE command used to save some record's changes done in TextBox return error message due to column value too long, I have added a property in custom Textbox to inform directly user that value's size is overlapped.

Aquí está mi formulario

enter image description here

Here is VB.Net code used to initialize MaxStringLength propiedades

    Private Sub PushColumnConstraints(dr As IDataReader)
        Dim tb As DataTable = dr.GetSchemaTable()
    
        Dim nColIndex As Integer = -1
    
        For Each col As DataColumn In tb.Columns
            If col.ColumnName = "ColumnSize" Then
                nColIndex = col.Ordinal
                Exit For
            End If
        Next
    
        If nColIndex < 0 Then
            oT.ThrowException("[ColumnSize] columns's index not found !")
            Exit Sub
        End If
    
        txtCodePays.MaxStringLength = tb.Rows(0).Item(nColIndex)
        txtPays.MaxStringLength = tb.Rows(1).Item(nColIndex)
        txtShortCodePays.MaxStringLength = tb.Rows(2).Item(nColIndex)
        txtDefaultDevise.MaxStringLength = tb.Rows(3).Item(nColIndex)
    End Sub

In For loop, program search index of field contained in ColumnSize valor de la columna.

MaxStringLength property is assigned using following syntax

tb.Rows(%TEXT-BOX-INDEX%).Item(nColIndex)

.Rows(%TEXT-BOX-INDEX%) is used to identify columna metadata in SQL SELECT !

.Item(nColIndex) is used to get a specific column's metadata value

Item(n) can return a String or an Integer but VB.Net do implicit conversion when necessary.

This line of code can also be written shortly

tb.Rows(%TEXT-BOX-INDEX%)(nColIndex)
tb(%TEXT-BOX-INDEX%)(nColIndex)

but it is not readable !

Precaución: MaxStringLength is a custom property. It is not part of normal TextBox.

In print screen above, you can see that program indicates to user that length is too big for Code Pays (3 lettres) TextBox. Error's message is displayed in StatusBar at bottom of Form.

This information is displayed before clicking on SAVE button that generates an SQL UPDATE mando.

Code used that call PushColumnConstraints method is following

    Public Sub FillPanel()
    
        SQL =
    <sql-select>
    
        SELECT code_pays
              ,nom
              ,code_pays_short
              ,default_devise
          FROM pays
          ORDER BY nom
            
    </sql-select>
    
        Dim cmd As New NpgsqlCommand(SQL, cn)
        Dim dr As NpgsqlDataReader
    
        Try
            dr = cmd.ExecuteReader()
        Catch ex As Exception
            ThrowException(ex)
        End Try
    
        Call PushColumnConstraints(dr)

respondido 01 mar '22, 07:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.