如何使用C语言和esent.lib在ESE中读取表中的列名?

时间:2019-07-14 20:11:12

标签: c extensible-storage-engine

我需要一个代码示例。我想看看我们如何枚举表中的列名。 (对我来说,使用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编程的良好指南,或者只是一些描述其工作原理的资源,请与我分享。 (尽管我在Google上搜索了很多,但不要为您的资源分享明显的内容)

2 个答案:

答案 0 :(得分:1)

内部表“ MSysObjects”(作为服务表存在于每个ESE数据库中)在我们中间有2个列:“类型”和“名称”。

    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,则意味着我们得到的记录描述的是表,如果type == 2,则描述了column。 (还有其他类型)有严格的顺序,首先您将获得类型1(表)的记录,然后将获得类型2的记录,该记录描述该表的列(此时buf保留列名),然后可以获取具有引用该表的其他类型(类型== 1除外)的记录。最后,您将获得类型1的记录,这意味着我们获得的下一个信息是关于另一个表的。

    }

请随意说我的英语很糟糕,我写了一些垃圾,然后我会尝试用其他方式解释:)

答案 1 :(得分:0)

如果您只想在不使用MSysObjects的情况下为特定表提供列表的列名,这就是我的方法。由“ JetGetTableColumnInfo”创建的临时表仅包含列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'\0';

            //********
            // 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来简化过程,但这对我来说很好。是的,我的代码看起来过时了-我陷入了匈牙利语!