如何获取MS Access数据库表的字段名称?
我可以使用SQL查询,还是有C#代码来执行此操作?
答案 0 :(得分:8)
使用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());
}
}
兴趣点:
对于我的测试表,输出为:
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>
答案 1 :(得分:6)
这将适用于sql server 2005及更高版本:
select * from INFORMATION_SCHEMA.COLUMNS
where TABLE_Name='YourTableName'
order by ORDINAL_POSITION
答案 2 :(得分:4)
运行此查询:
select top 1 *
From foo
然后遍历结果集中的列表字段(和返回值)以获取字段名称。
答案 3 :(得分:2)
您是否在询问如何在数据库中获取表的列名?
如果是这样,它完全取决于您使用的数据库服务器。
在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'
答案 4 :(得分:1)
使用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#进行了测试。
答案 5 :(得分:1)
此代码会将表的所有列名打印为具有所有列名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"; } }
}
答案 6 :(得分:0)
根据您使用的数据库引擎,您可以轻松地在数据库系统表中查询该信息
对于访问我无法找到答案,我知道你can see the sys tables访问,从那里你可以尝试确定信息的位置,但我不确定如何做这部分。尝试使用一个例子,但现在到了
答案 7 :(得分:0)
对于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(); }
}
}
答案 8 :(得分:0)
我对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数据库(约束和所有)的脚本。
虽然我已经看到这个帖子中的其他人提到了获取Schema,但似乎有些实现过于复杂了。 。
希望有所帮助!
答案 9 :(得分:0)
请参见下面的功能
返回属性名称列表。
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;
}
}