如何在 Anylogic 中动态读取数据库列

How to dynamically read database columns in Anylogic

背景优先:我有以下代理类型:activitypathway路径 是包含活动 群体的代理。 活动 包含给其他代理人的具体说明(命令)。 pathways 是这些指令的集合。 pathway 集合是通过数据库定义的,其中每行是 1 个通路代理,每列是 activity 的字符串 ID,单元格值为 0、1、2 等,具体取决于分配给该路径的每个 activity 的数量。

目标:我需要在代理启动时

路径代理中创建活动

我尝试过的: 我在 Main 中创建了 activities 人口。每个 pathway 都有一个 activityList,其中包含所有活动的字符串 ID。目的是当单元格值为 1 或以上时,代码将从 main 中选择相应的 activity 代理并将其放入 pathway[ 中的人口中=35=]。下面的代码,我从其他帖子中注意到索引用于遍历行,但这似乎不适用于列。

问题:我无法获得根据字符串 ID 列表动态搜索列的代码

activityIndex = 0;
// there are 115 activities in the list, the code would repeat for each one
while (activityIndex <= 114)
{
    activityName = activityList.get(activityIndex);
// search below returns the cell value from row with pathway ID = agAssess
// it searches the column with string ID matching activityName
// note: error returned as the database does not contain a column named "activityName"
// in this case "activityName" in the search below would need to be replaced with the parameter's value
// error message: activityName cannot be resolved or is not a field
    double value = selectFrom(activity_groups_assess).
        where(activity_groups_assess.code.eq(agAssess)).
        uniqueResult(activity_groups_assess.activityName);
// if the value > 0, create agent with string ID activityName
// for agents with value > 1, multiple agents with the same string ID would be created, hence while function
    while (value > 0)
    {
// find the agent with the same string ID
        Activity newActivity = findFirst(main.activities, p -> p.code == activityName);
// add agent to population activitiesAssess
// error when adding agent: Description: The method add_activitiesAssess() in the type ClinicalPathway is not applicable for the arguments (Activity).
        add_activitiesAssess( newActivity );
        value--;
    }
    activityIndex++;
}

也许这有帮助:

您可以使用以下类型将对数据库的引用 table 存储在变量中:

com.mysema.query.sql.RelationalPathBase

在特定列中选择double(int、String等)类型的值时,您可以通过索引调用variable.getColumns().get(index)获取该列。然后你需要将它转换为相应的类型,如下所示:

List<Double> resultRows = selectFrom(variable).where( ( (com.mysema.query.types.path.NumberPath<Double>) variable.getColumns().get(1) ).eq(2.0)) .list(( (com.mysema.query.types.path.NumberPath<Double>) variable.getColumns().get(1) ));

我能先澄清一下吗,所以你有一个 table 看起来像这样:

Pathway id Activity 1 Activity 2 Activity 3
one 0 3 2
two 1 0 1
three 1 1 0

并且您想在路径 'one' 代理中创建 3 'Activity 2' 和 2 'Activity 3' 代理。对吗?

如果是这样,恐怕没有一种干净的方法可以做到这一点 'out-of-the-box'。我建议一次读取一行,然后调用 'add_activity'。所以代码看起来像下面这样。

List<Tuple> records = selectFrom(testdbtable).list();
records.forEach(rec -> {
    String pathway = rec.get(testdbtable.pathway);
    testdbtable.getColumns().forEach(col -> {
        String activityName = col.getMetadata().getName(); // <-  this is the column name which in your case is Activity Id
        if (!activityName.equalsIgnoreCase(testdbtable.pathway.getMetadata().getName())) {
            int activityCount = (int)rec.get(col);
            // ... and below you add Acitivity agent to Pathway agent
            traceln("Pathway [%s], Activity [%s] -> count is %d", pathway, activityName, activityCount); 
        }
    });
});

以上代码产生以下输出:

Pathway [one], Activity [activity1] -> count is 0
Pathway [one], Activity [activity2] -> count is 3
Pathway [one], Activity [activity3] -> count is 2
Pathway [one], Activity [al_id] -> count is 0
Pathway [two], Activity [activity1] -> count is 1
Pathway [two], Activity [activity2] -> count is 0
Pathway [two], Activity [activity3] -> count is 1
Pathway [two], Activity [al_id] -> count is 1
Pathway [three], Activity [activity1] -> count is 1
Pathway [three], Activity [activity2] -> count is 1
Pathway [three], Activity [activity3] -> count is 0
Pathway [three], Activity [al_id] -> count is 2

所以您只需要在 traceln 语句之后添加用于创建适当 Activity 代理的代码。希望对您有所帮助。