2009-05-13 37 views

Trả lời

5

này sẽ làm việc trên SQL Server 2005 trở lên:

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

nhưng tôi làm việc trong Access và truy cập nó không hoạt động – Gold

+1

@Gold, thêm thẻ "truy cập" vào câu hỏi! –

+0

Thao tác này không hoạt động trong quyền truy cập. Bạn có thể giải thích INFORMATION_SCHEMA là gì không? –

0

Tùy thuộc vào động cơ DB sử dụng của bạn, bạn có thể dễ dàng truy vấn các bảng hệ thống DB để biết thông tin rằng

Để truy cập tôi không thể tìm ra câu trả lời tôi biết bạn can see the sys tables trong việc tiếp cận và từ đó bạn có thể thử và xác định nơi thông tin đó là nhưng im không thực sự chắc chắn làm thế nào để làm điều này một phần. đã thử sử dụng một ví dụ nhưng đã nhận ngay bây giờ

+1

MSysObjects chứa danh sách các bảng, không có trường nào tương đương với các trường. –

2

Bạn có hỏi cách bạn có thể lấy tên cột của một bảng trong Cơ sở dữ liệu không?

Nếu điều đó hoàn toàn phụ thuộc vào Máy chủ cơ sở dữ liệu bạn đang sử dụng.

Trong SQL 2005 bạn có thể chọn từ bảng information_schema Xem

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

TRÊN SQL 2000 bạn có thể tham gia sysobjects để syscolumns để có được các thông tin

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' 
+0

Câu trả lời của bạn áp dụng cho Access/Jet như thế nào? –

+0

-1 Anh ấy hỏi về MS Access. –

+1

Xin lỗi, tôi lấy lại -1 của tôi, câu hỏi ban đầu không rõ ràng về điểm đó. –

4

Chạy truy vấn này:

select top 1 * 
From foo 

và sau đó đi bộ các trường danh sách (và giá trị trả lại) trong tập kết quả để lấy tên trường.

+0

Nếu tất cả những gì bạn cần là tên * cột * thì cách tiếp cận nhanh chóng và dơ bẩn này là IMO tốt. Lưu ý bạn có thể thêm WHERE 0 = 1 (hoặc tương tự) để đảm bảo không có dữ liệu được trả về. – onedaywhen

+0

Điều này không hoạt động nếu bạn đã xác định phụ đề. Nó hiển thị chú thích thay thế. – jpmc26

1

Sử dụng các lớp tự động hóa DAO. Bạn có thể đã có một thư viện interop cho nó trong cài đặt Visual Studio của bạn. Nếu không, nó dễ dàng, đủ để tạo ra một; chỉ cần thêm một tham chiếu đến thư viện COM DAO.

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(); 

Việc này dễ dàng như truy vấn bảng hệ thống (mà tôi thấy có vấn đề trong Access) và bạn có thể nhận được nhiều thông tin bổ sung theo cách này.

EDIT: Tôi đã sửa đổi mã từ những gì tôi đã đăng ngày hôm qua, mà tôi vừa dịch từ VB.NET và thiếu một vài phần. Tôi đã viết lại nó và thử nghiệm nó trong C# trong VS2008.

+0

Từ C#, chức năng Danh mục ADO có thể dễ dàng hơn. –

+1

IIRC các cuộc gọi đến OpenSchema để có được các khung nhìn THÔNG TIN SCHEMA không đơn giản đối với C# và có thể không đáng giá cho các tên cột. – onedaywhen

8

Sử dụng IDataReader.GetSchemaTable()

Dưới đây là một ví dụ thực tế mà truy cập vào schema bảng và in nó đơn giản và trong XML (chỉ để xem những thông tin nào bạn nhận được):

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()); 
    } 
} 

điểm đáng chú ý:

  1. Không trả lại bất kỳ dữ liệu nào bằng cách đưa ra mệnh đề where luôn luôn đánh giá sai. Tất nhiên điều này chỉ áp dụng nếu bạn không quan tâm đến dữ liệu :-).
  2. Sử dụng IDataReader.GetSchemaTable() để lấy DataTable với thông tin chi tiết về bảng thực tế.

Đối với bảng thử nghiệm của tôi đầu ra là:

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> 
+0

Không phải là 'conn.Close()' dư thừa, vì kết nối được tạo bên trong một cấu trúc 'sử dụng', sẽ đóng kết nối khi thực thi tồn tại cấu trúc? –

0

cho SQL microsoft trong C# bạn có thể làm như sau:

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); 

do đó tạo ra một bản đồ của tên cột vào nó chỉ mục có thể được sử dụng như sau:

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(); } 
    } 
} 
0

Tôi đã có may mắn với thuộc tính GetSchema của OleDb.Connection:

Một lớp học để cung cấp dữ liệu cột. Điều này trả về tất cả các cột trong cơ sở dữ liệu. Kết quả là DataTable sau đó có thể được lọc bởi tên cột tương ứng (chủ yếu) cho những tìm thấy trong một INFORMATION_SCHEMA tiêu chuẩn (mà MS Access KHÔNG cung cấp cho chúng tôi):

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; 
     } 

    } 

Sau đó, tiêu thụ các lớp trong một khá thô và ví dụ không thanh lịch và lọc trên 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; 

    } 

Lưu ý rằng tôi không giả vờ rằng đây là mã hết sức tốt. Nó chỉ là một ví dụ. Nhưng tôi đã sử dụng một cái gì đó như thế này trên một số dịp, và trên thực tế thậm chí tạo ra một ứng dụng để kịch bản ra toàn bộ cơ sở dữ liệu MS Access (contraints và tất cả) bằng cách sử dụng phương pháp tương tự.

Trong khi tôi đã thấy những người khác trong chuỗi này đề cập đến lược đồ nhận được, có vẻ như một số việc thực hiện quá phức tạp. . .

Hy vọng điều đó sẽ hữu ích!

1

Bộ luật này sẽ in tất cả tên cột của một bảng như một lớp học với getter tài sản của tất cả các tên cột mà sau đó có thể được sử dụng trong c# đang

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 

Output:

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"; } } 

} 
Các vấn đề liên quan