【问题标题】:Using GetSchemaTable() to retrieve only column names使用 GetSchemaTable() 仅检索列名
【发布时间】:2012-08-28 14:01:54
【问题描述】:

是否可以使用GetSchemaTable() 仅检索列名?

我一直在尝试使用这种方法(仅)检索列名,是否可能。

  DataTable table = myReader.GetSchemaTable();

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

这段代码检索了很多不需要的表数据,我只需要一个包含 列名!:

【问题讨论】:

    标签: c# sql


    【解决方案1】:

    你需要使用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:

    查询只返回列信息。使用 SchemaOnly 时, 用于 SQL Server 的 .NET Framework 数据提供程序位于语句之前 使用 SET FMTONLY ON 执行。

    列名在每一行的第一列。我认为不可能省略其他列信息,如ColumnOrdinal,ColumnSize,NumericPrecision 等,因为在这种情况下您不能使用reader.GetString,而只能使用reader.GetSchemaTable

    但如果你只想要列名,你的循环是不正确的:

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

    【讨论】:

    • 仍然返回所有数据 :-( 可能我的循环有问题。
    • @user1495962:列名在每一行的第一列。我认为不可能省略其他列信息,例如 ColumnOrdinal,ColumnSize,NumericPrecision 等。编辑了我的答案
    【解决方案2】:

    如果您只想显示列名,请将您的代码更改为以下内容。您的原始代码不仅尝试显示列名,还尝试显示实际数据值。

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

    【讨论】:

    • 尝试设置它没有运气
    【解决方案3】:

    这将为您提供所有列名,您可以将它们放在string[] 中,然后随心所欲地使用它们。

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

    【讨论】:

      【解决方案4】:
      //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);
        }
      

      【讨论】:

        【解决方案5】:

        我在我的 VB.Net 程序中使用相同的技术在 custom TextBox 上添加 MAX-STRING-LENGTH 约束。

        我使用 SQL SELECT 命令获取 4 列的值

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

        我使用IDataReader 对象返回的结果来填充DataGridView

        最后,我在包含 4 个TextBoxPanel 中显示每一行的字段。

        为了避免 SQL UPDATE 命令用于保存 TextBox 中所做的某些记录的更改,由于列值太长而返回错误消息,我在自定义 Textbox 中添加了一个属性,以直接通知用户值的大小重叠。

        这是我的表格

        这是用于初始化MaxStringLength属性的VB.Net代码

            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
        

        For循环中,程序搜索ColumnSize列值中包含的字段的索引。

        MaxStringLength 属性使用以下语法分配

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

        .Rows(%TEXT-BOX-INDEX%) 用于标识 SQL SELECT 中的列的元数据!

        .Item(nColIndex) 用于获取特定列的元数据值

        Item(n) 可以返回 String 或 Integer,但 VB.Net 会在必要时进行隐式转换。

        这行代码也可以很快写出来

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

        但它不可读!

        注意:MaxStringLength 是自定义属性。它不是普通 TextBox 的一部分。

        在上面的打印屏幕中,您可以看到程序向用户指示Code Pays (3 lettres) TextBox 的长度太大。 错误消息显示在表单底部的StatusBar 中。

        此信息在单击生成 SQL UPDATE 命令的SAVE 按钮之前显示。

        调用PushColumnConstraints方法的代码如下

            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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多