如何使用C语言和esent.lib读取ESE中table中的列名?
How to read columns names in table in ESE using C language and esent.lib?
我需要一个代码示例。我想看看我们如何枚举 table 中的列名。 (esent.dll/esent.lib和C语言对我来说必不可少)
我尝试使用附加代码(找到了一个指南,但它没有像我预期的那样工作)。
JET_COLUMNLIST column_info;
JET_RETRIEVECOLUMN j_rc[4];
err = JetGetTableColumnInfo(sessionID, curr_table.tableID, NULL, &column_info, sizeof(JET_COLUMNLIST), JET_ColInfoList);
j_rc[0].columnid = column_info.columnidcolumnname;
j_rc[0].cbData = sizeof(char)*JET_cbNameMost;
j_rc[0].itagSequence = 1;
j_rc[0].grbit = 0;
char buf[JET_cbNameMost] = { 0 };
j_rc[0].pvData = buf;
printf("\nRetrieving columns information:\n");
printf("Row\tId\tType\tName:\n");
unsigned long columns_qnt = 0;
for (err = JetMove(sessionID, curr_table.tableID, JET_MoveFirst, 0);
JET_errSuccess == err;
err = JetMove(sessionID, curr_table.tableID, JET_MoveNext, 0))
{
err = JetRetrieveColumns(sessionID, curr_table.tableID, j_rc, 4);
columns_qnt++;
printf("%u\t%s\n", columns_qnt, buf);
memset(buf, 0, JET_cbNameMost);
}
请举个例子。如果您知道 ESE C 编程的良好指南或只是一些描述其工作原理的资源,请与我分享。 (尽管我在谷歌上搜索了很多,但不要害羞为您分享明显的资源)
table"MSysObjects"(作为服务存在于每个 ESE 数据库中 table)内部有 2 个对我们有用的列:"Type" 和 "Name"。
JetOpenTable(sessionID, dbid, "MSysObjects", NULL, NULL, JET_bitTableSequential, &tableID);
JET_COLUMNBASE j_cb_name, j_cb_type, j_cb_coltype;
JetGetColumnInfo(sessionID, dbid, "MSysObjects", "Name", &j_cb_name, sizeof(JET_COLUMNBASE), JET_ColInfoBase);
JetGetColumnInfo(sessionID, dbid, "MSysObjects", "Type", &j_cb_type, sizeof(JET_COLUMNBASE), JET_ColInfoBase);
JET_RETRIEVECOLUMN j_rc[2];
这里我们填充结构 JET_RETRIEVECOLUMN 以通过 JetRetrieveColumns
获取这 2 列
j_rc[0].columnid = j_cb_name.columnid;
j_rc[0].cbData = 1024;
j_rc[0].itagSequence = 1;
j_rc[0].grbit = NULL;
char buf[1024] = { 0 };
j_rc[0].pvData = buf;
j_rc[1].columnid = j_cb_type.columnid;
j_rc[1].cbData = sizeof(unsigned short);
j_rc[1].itagSequence = 1;
j_rc[1].grbit = NULL;
unsigned short type;
j_rc[1].pvData = &type;
for (err = JetMove(sessionID, root_tableID, JET_MoveFirst, 0);
JET_errSuccess == err;
err = JetMove(sessionID, root_tableID, JET_MoveNext, 0))
{
JetRetrieveColumns(sessionID, root_tableID, j_rc, 2);
我们在这里找到了他们。如果 type == 1 意味着,我们得到的记录描述了一个 table,如果 type == 2,那么它描述了一个列。 (还有其他类型)有严格的顺序,首先你会得到类型1的记录(table)然后你会得到类型2的记录,它描述了那个table的列(在那一刻buf保留列名),那么您可以获得引用该 table 的其他类型(类型 == 1 除外)的记录。最后你会得到类型 1 的记录,这意味着我们得到的下一个信息是关于另一个 table。
}
尽管说我的英语很糟糕,我写了一些垃圾,然后我会尝试用其他方式解释:)
如果您只想要一个 list 特定 table 的列名称而不使用 MSysObjects,这是我的方法。 "JetGetTableColumnInfo" 创建的临时 table 只包含列 ID 和列名称,所以速度非常快:
JET_ERR GetEseTableColumnNames(JET_SESID hEseSession, JET_TABLEID hEseTable)
{ JET_ERR rc;
JET_COLUMNLIST cl { };
/* Sort order for the temporary table is column name order */
rc = ::JetGetTableColumnInfo(hEseSession, hEseTable, nullptr, &cl, sizeof(cl), JET_ColInfoList | JET_ColInfoGrbitMinimalInfo);
/* Temporary table ("cl.tableid") is opened and positioned on first record */
if (rc == JET_errSuccess && cl.cRecord > 0)
{ wchar_t wszColumnName[MAX_ESE_OBJECT_NAME + 1]; // ESE doesn't play well with std::strings
unsigned long cbActual;
for (uint32_t i = 0; i < cl.cRecord; ++i)
{
rc = ::JetRetrieveColumn(hEseSession, cl.tableid, cl.columnidcolumnname, wszColumnName, sizeof(wszColumnName), &cbActual, 0, nullptr);
if (rc == JET_errSuccess)
{
/* ESE does not null terminate strings */
wszColumnName[cbActual / sizeof(wchar_t)] = L'[=10=]';
//********
// Okay, so do something with the column name here
//********
/* Next record in temporary table */
if (i < cl.cRecord - 1)
::JetMove(hEseSession, cl.tableid, JET_MoveNext, 0);
}
else
break;
}
}
/* Close the temporary table */
::JetCloseTable(hEseSession, cl.tableid);
return rc;
}
我知道其他人使用 MSysObjects 来 short-cut 这个过程,但这对我来说很好用。是的,我的代码看起来很老套——我被困在匈牙利语中!
我需要一个代码示例。我想看看我们如何枚举 table 中的列名。 (esent.dll/esent.lib和C语言对我来说必不可少)
我尝试使用附加代码(找到了一个指南,但它没有像我预期的那样工作)。
JET_COLUMNLIST column_info;
JET_RETRIEVECOLUMN j_rc[4];
err = JetGetTableColumnInfo(sessionID, curr_table.tableID, NULL, &column_info, sizeof(JET_COLUMNLIST), JET_ColInfoList);
j_rc[0].columnid = column_info.columnidcolumnname;
j_rc[0].cbData = sizeof(char)*JET_cbNameMost;
j_rc[0].itagSequence = 1;
j_rc[0].grbit = 0;
char buf[JET_cbNameMost] = { 0 };
j_rc[0].pvData = buf;
printf("\nRetrieving columns information:\n");
printf("Row\tId\tType\tName:\n");
unsigned long columns_qnt = 0;
for (err = JetMove(sessionID, curr_table.tableID, JET_MoveFirst, 0);
JET_errSuccess == err;
err = JetMove(sessionID, curr_table.tableID, JET_MoveNext, 0))
{
err = JetRetrieveColumns(sessionID, curr_table.tableID, j_rc, 4);
columns_qnt++;
printf("%u\t%s\n", columns_qnt, buf);
memset(buf, 0, JET_cbNameMost);
}
请举个例子。如果您知道 ESE C 编程的良好指南或只是一些描述其工作原理的资源,请与我分享。 (尽管我在谷歌上搜索了很多,但不要害羞为您分享明显的资源)
table"MSysObjects"(作为服务存在于每个 ESE 数据库中 table)内部有 2 个对我们有用的列:"Type" 和 "Name"。
JetOpenTable(sessionID, dbid, "MSysObjects", NULL, NULL, JET_bitTableSequential, &tableID);
JET_COLUMNBASE j_cb_name, j_cb_type, j_cb_coltype;
JetGetColumnInfo(sessionID, dbid, "MSysObjects", "Name", &j_cb_name, sizeof(JET_COLUMNBASE), JET_ColInfoBase);
JetGetColumnInfo(sessionID, dbid, "MSysObjects", "Type", &j_cb_type, sizeof(JET_COLUMNBASE), JET_ColInfoBase);
JET_RETRIEVECOLUMN j_rc[2];
这里我们填充结构 JET_RETRIEVECOLUMN 以通过 JetRetrieveColumns
获取这 2 列 j_rc[0].columnid = j_cb_name.columnid;
j_rc[0].cbData = 1024;
j_rc[0].itagSequence = 1;
j_rc[0].grbit = NULL;
char buf[1024] = { 0 };
j_rc[0].pvData = buf;
j_rc[1].columnid = j_cb_type.columnid;
j_rc[1].cbData = sizeof(unsigned short);
j_rc[1].itagSequence = 1;
j_rc[1].grbit = NULL;
unsigned short type;
j_rc[1].pvData = &type;
for (err = JetMove(sessionID, root_tableID, JET_MoveFirst, 0);
JET_errSuccess == err;
err = JetMove(sessionID, root_tableID, JET_MoveNext, 0))
{
JetRetrieveColumns(sessionID, root_tableID, j_rc, 2);
我们在这里找到了他们。如果 type == 1 意味着,我们得到的记录描述了一个 table,如果 type == 2,那么它描述了一个列。 (还有其他类型)有严格的顺序,首先你会得到类型1的记录(table)然后你会得到类型2的记录,它描述了那个table的列(在那一刻buf保留列名),那么您可以获得引用该 table 的其他类型(类型 == 1 除外)的记录。最后你会得到类型 1 的记录,这意味着我们得到的下一个信息是关于另一个 table。
}
尽管说我的英语很糟糕,我写了一些垃圾,然后我会尝试用其他方式解释:)
如果您只想要一个 list 特定 table 的列名称而不使用 MSysObjects,这是我的方法。 "JetGetTableColumnInfo" 创建的临时 table 只包含列 ID 和列名称,所以速度非常快:
JET_ERR GetEseTableColumnNames(JET_SESID hEseSession, JET_TABLEID hEseTable)
{ JET_ERR rc;
JET_COLUMNLIST cl { };
/* Sort order for the temporary table is column name order */
rc = ::JetGetTableColumnInfo(hEseSession, hEseTable, nullptr, &cl, sizeof(cl), JET_ColInfoList | JET_ColInfoGrbitMinimalInfo);
/* Temporary table ("cl.tableid") is opened and positioned on first record */
if (rc == JET_errSuccess && cl.cRecord > 0)
{ wchar_t wszColumnName[MAX_ESE_OBJECT_NAME + 1]; // ESE doesn't play well with std::strings
unsigned long cbActual;
for (uint32_t i = 0; i < cl.cRecord; ++i)
{
rc = ::JetRetrieveColumn(hEseSession, cl.tableid, cl.columnidcolumnname, wszColumnName, sizeof(wszColumnName), &cbActual, 0, nullptr);
if (rc == JET_errSuccess)
{
/* ESE does not null terminate strings */
wszColumnName[cbActual / sizeof(wchar_t)] = L'[=10=]';
//********
// Okay, so do something with the column name here
//********
/* Next record in temporary table */
if (i < cl.cRecord - 1)
::JetMove(hEseSession, cl.tableid, JET_MoveNext, 0);
}
else
break;
}
}
/* Close the temporary table */
::JetCloseTable(hEseSession, cl.tableid);
return rc;
}
我知道其他人使用 MSysObjects 来 short-cut 这个过程,但这对我来说很好用。是的,我的代码看起来很老套——我被困在匈牙利语中!