为什么在自定义函数内无法用objByName找到函数内定义的表

我在DolphinDB database GUI中定义了下面函数:

def myfunc(){
 t1 = table(1..100 as id)
 re = parseExpr("select * from t1 where id in (1..10)").eval()
 return re
}
myfunc()

执行后报错:
myfunc() => myfunc: re = ::evaluate(parseExpr("select * from t1 where id in (1..10)")) => Can't find the object with name t1。
我把它改成如下:

def myfunc(){
 t1 = table(1..100 as id)
 re = select * from objByName("t1")
 return re
}
myfunc()

执行后还是报错:
myfunc() => myfunc: re = select * from objByName("t1") => Can't find the object with name t1。
请问这是为什么?

请先 登录 后评论

1 个回答

Juntao Wang

用户手册对objByName有如下说明:

DolphinDB在执行脚本之前先解析脚本。解析脚本的过程是检查变量是否在本地定义。如果没有在本地定义,则抛出异常。

假设我们在本地定义一个函数,然后在远程节点上执行。这个函数会查询共享表。但是,共享表在远程节点上而不在本地节点上。如果我们在函数的SQL语句中直接调用表名,系统将不能解析脚本。

为了解决这个问题,系统函数objByName在执行时会根据名称返回对象。如果没有指定sharedVar,系统首先搜索会话中的局部变量,再搜索共享变量。如果sharedVar为true,表示只搜索共享变量。如果sharedVar为false,表示只搜索局部变量。

简单的说,objByName优先搜索节点中定义的共享变量,然后再去搜索当前会话中定义的变量,不会去搜索函数内部定义的的局部变量。parseExpr中的变量搜索同objByName。

要解决上面的代码的问题,可以使用sql函数动态生成:

def myfunc(){
    t1 = table(1..100 as id)
    return sql(sqlCol("*"), t1, <id in 1..10>).eval()
}
myfunc()
请先 登录 后评论