簡體   English   中英

如何獲取數據庫表的字段名稱?

[英]How can I get the field names of a database table?

如何獲取 MS Access 數據庫表的字段名稱?

是否有我可以使用的 SQL 查詢,或者是否有 C# 代碼來執行此操作?

使用IDataReader.GetSchemaTable()

這是一個實際示例,它訪問表模式並以 XML 格式打印它(只是為了查看您獲得的信息):

class AccessTableSchemaTest
{
    public static DbConnection GetConnection()
    {
        return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\\Test.mdb");
    }

    static void Main(string[] args)
    {
        using (DbConnection conn = GetConnection())
        {
            conn.Open();

            DbCommand command = conn.CreateCommand();
            // (1) we're not interested in any data
            command.CommandText = "select * from Test where 1 = 0";
            command.CommandType = CommandType.Text;

            DbDataReader reader = command.ExecuteReader();
            // (2) get the schema of the result set
            DataTable schemaTable = reader.GetSchemaTable();

            conn.Close();
        }

        PrintSchemaPlain(schemaTable);

        Console.WriteLine(new string('-', 80));

        PrintSchemaAsXml(schemaTable);

        Console.Read();
    }

    private static void PrintSchemaPlain(DataTable schemaTable)
    {
        foreach (DataRow row in schemaTable.Rows)
        {
            Console.WriteLine("{0}, {1}, {2}",
                row.Field<string>("ColumnName"),
                row.Field<Type>("DataType"),
                row.Field<int>("ColumnSize"));
        }
    }

    private static void PrintSchemaAsXml(DataTable schemaTable)
    {
        StringWriter stringWriter = new StringWriter();
        schemaTable.WriteXml(stringWriter);
        Console.WriteLine(stringWriter.ToString());
    }
}

興趣點:

  1. 不要通過給出始終計算為 false 的 where 子句來返回任何數據。 當然,這僅適用於您對數據不感興趣的情況:-)。
  2. 使用 IDataReader.GetSchemaTable() 獲取包含有關實際表的詳細信息的 DataTable。

對於我的測試表,輸出是:

ID, System.Int32, 4
Field1, System.String, 50
Field2, System.Int32, 4
Field3, System.DateTime, 8
--------------------------------------------------------------------------------
<DocumentElement>
  <SchemaTable>
    <ColumnName>ID</ColumnName>
    <ColumnOrdinal>0</ColumnOrdinal>
    <ColumnSize>4</ColumnSize>
    <NumericPrecision>10</NumericPrecision>
    <NumericScale>255</NumericScale>
    <DataType>System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</DataType>
    <ProviderType>3</ProviderType>
    <IsLong>false</IsLong>
    <AllowDBNull>true</AllowDBNull>
    <IsReadOnly>false</IsReadOnly>
    <IsRowVersion>false</IsRowVersion>
    <IsUnique>false</IsUnique>
    <IsKey>false</IsKey>
    <IsAutoIncrement>false</IsAutoIncrement>
  </SchemaTable>
  [...]
</DocumentElement>

這將適用於 sql server 2005 及更高版本:

select * from INFORMATION_SCHEMA.COLUMNS 
where TABLE_Name='YourTableName'
order by ORDINAL_POSITION

運行此查詢:

select top 1 *
From foo

然后遍歷結果集中的列表字段(和返回值)以獲取字段名稱。

您是在問如何獲取數據庫中表的列名嗎?

如果是這樣,它完全取決於您使用的數據庫服務器。

在 SQL 2005 中,您可以從 INFORMATION_SCHEMA.Columns 視圖中進行選擇

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'

在 SQL 2000 中,您可以將 SysObjects 加入 SysColumns 以獲取信息

SELECT     
    dbo.sysobjects.name As TableName
    , dbo.syscolumns.name AS FieldName
FROM
    dbo.sysobjects 
    INNER JOIN dbo.syscolumns 
         ON dbo.sysobjects.id = dbo.syscolumns.id
WHERE
    dbo.sysobjects.name = 'MyTable'

此代碼將表的所有列名打印為具有所有列名的getter屬性的類,然后可以在c#代碼中使用

    declare @TableName sysname = '<EnterTableName>'
    declare @Result varchar(max) = 'public class ' + @TableName + '
    {'

    select @Result = @Result + '
        public static string ' + ColumnName + ' { get { return "'+ColumnName+'"; } }
    '
    from
    (
        select
            replace(col.name, ' ', '_') ColumnName,
            column_id ColumnId
        from sys.columns col
            join sys.types typ on
                col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
        where object_id = object_id(@TableName)
    ) t
    order by ColumnId

    set @Result = @Result  + '
    }'

    print @Result

輸出:

 public class tblPracticeTestSections
 {
   public static string column1 { get { return "column1"; } }

   public static string column2{ get { return "column2"; } }

   public static string column3{ get { return "column3"; } }

   public static string column4{ get { return "column4"; } }

 }

使用 DAO 自動化類。 你的 Visual Studio 安裝中可能已經有一個互操作庫。 如果沒有,創建一個就很容易了; 只需添加對 DAO COM 庫的引用。

using dao;
...
DBEngineClass dbengine = new DBEngineClass();
dbengine.OpenDatabase(path, null, null, null);
Database database = dbengine.Workspaces[0].Databases[0];
List<string> fieldnames = new List<string>();
TableDef tdf = database.TableDefs[tableName];
for (int i = 0; i < tdf.Fields.Count; i++)
{
    fieldnames.Add(tdf.Fields[i].Name);
}
database.Close();
dbengine.Workspaces[0].Close();

這就像查詢系統表一樣簡單(我發現它在 Access 中存在問題),並且您可以通過這種方式獲得很多附加信息。

編輯:我已經修改了我昨天發布的代碼,我剛剛從 VB.NET 翻譯了它,並且缺少了幾部分。 我已經重寫它並在 VS2008 中用 C# 測試它。

請參閱下面的功能:

返回屬性名稱列表。

public static List<string> GetTableAttributeNames(DatabaseAccess dba, string tableName)
{
    List<string> list = new List<string>();

    string sSql = string.Format("select * from [{0}] where 1 = 2", tableName);
    using (DataSet ds = dba.GetDataSet(sSql))
    {
        if (ds == null || ds.Tables == null 
            || ds.Tables.Count != 1 || ds.Tables[0].Columns == null)
            return list;

        for (int ndx = 0; ndx < ds.Tables[0].Columns.Count; ndx++)
        {
            DataColumn col = ds.Tables[0].Columns[ndx];
            if (col.AutoIncrement)
                continue;

            string attrName = col.ColumnName;
            list.Add(attrName);
        }
        return list;
    }
}

對於 c# 中的 microsoft SQL,您可以執行以下操作:

Dictionary<string, int> map = 
(from DataRow row in Schema.Rows
 let columnName = (string)row["ColumnName"]
  select columnName)
 .Distinct(StringComparer.InvariantCulture)
 .Select((columnName, index) => new { Key = columnName, Value = index })
 .ToDictionary(pair => pair.Key, pair => pair.Value);

因此創建了一個列名映射到其索引中,可以如下使用:

internal sealed class ColumnToIndexMap
{
    private const string NameOfColumn = "ColumnName";
    private DataTable Schema { get; set; }
    private Dictionary<string, int> Map { get; set; }

    public ColumnToIndexMap(DataTable schema)
    {
        if (schema == null) throw new ArgumentNullException("schema");
        Schema = schema;

        Map = (from DataRow row in Schema.Rows
               let columnName = (string)row[NameOfColumn]
               select columnName)
              .Distinct(StringComparer.InvariantCulture)
              .Select((columnName, index) => new { Key = columnName, Value = index })
              .ToDictionary(pair => pair.Key, pair => pair.Value);
    }

    int this[string name]
    {
        get { return Map[name]; }
    }

    string this[int index]
    {
        get { return Schema.Rows[index][NameOfColumn].ToString(); }
    }
}

我對 OleDb.Connection 的 GetSchema 屬性很幸運:

提供列數據的類。 這將返回數據庫中的所有列。 然后可以通過列名過濾生成的 DataTable,這些列名(主要)對應於標准 INFORMATION_SCHEMA(MS Access 不為我們提供)中找到的列名:

    class JetMetaData
    {
        /// <summary>
        /// Returns a datatable containing MetaData for all user-columns
        /// in the current JET Database. 
        /// </summary>
        /// <returns></returns>
        public static DataTable AllColumns(String ConnectionString)
        {
            DataTable dt;

            using (OleDbConnection cn = new OleDbConnection(ConnectionString))
            {
                cn.Open();
                dt = cn.GetSchema("Columns");
                cn.Close();
            }
            return dt;
        }

    }

然后,在一個相當粗糙且不那么優雅的示例中使用該類,並在 TABLE_NAME 上進行過濾:

    private void Form1_Load(object sender, EventArgs e)
    {
        DataTable dt = JetMetaData.AllColumns("", Properties.Settings.Default.JetConnection);
        String RowFilter = "TABLE_NAME = 'YourTableName'";
        DataView drv = dt.DefaultView;
        drv.RowFilter = RowFilter;

        DataGridView dgv = this.dataGridView1;

        dgv.DataSource = drv;

    }

請注意,我並沒有假裝這都是很好的代碼。 這只是一個例子。 但是我在很多場合都使用過這樣的東西,實際上甚至創建了一個應用程序來使用類似的方法編寫整個 MS Access 數據庫(約束和所有)的腳本。

雖然我在這個線程中看到其他人提到了 get Schema,但似乎某些實現過於復雜。 . .

希望有幫助!

根據您使用的數據庫引擎,您可以輕松查詢數據庫系統表以獲取該信息

對於訪問,我找不到答案,我知道您 可以看到訪問中 的 sys 表,從那里您可以嘗試確定該信息的位置,但我不確定如何執行此部分。 嘗試使用一個例子,但現在得到了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM