由于我们在Java中有try-catch,因此我可以在q kdb中找到trap-at。
但是我的要求是最后尝试尝试,即在try块中,我打开odbc连接,最后我要关闭odbc连接。
Sudo code:
try{
con=openODBCConnection(dbName);
//n statements;
}catch(Exception e){
catchingNotSoImpException(e)
}finally{
closeODBCCon(con);
}
答案 0 :(得分:5)
这是在kdb中使用try-catch-finally逻辑的相当通用的方法,它将try-catch分离出来,始终运行“ finally”功能。如果在try或catch中成功(如果需要),则返回输出,或者在try和catch均已中断的情况下返回错误代码,从而允许(潜在地)对中断进行更有用的调查和/或安全性:
tcf:{[t;c;f]
r:@[(1b;)value@;t;@[(1b;)c@;;(0b;)::]];
f[];
$[r 0;r 1;'`$r 1]}
最上面的一行是“ try-catch”部分。
@[(1b;)value@;t;@[(1b;)c@;;(0b;)::]]
该函数的调用方式如下:
tcf[(tryfunc;1;`a);catchfunc;finallyfunc]
因此输入必须是可以在kdb中value
输入的内容-符号,函数和参数列表或字符串。
这可以按原样使用,但有一个解释:
这里逻辑的关键部分是(1b;)
和(0b;)
以及@
在value
或c
函数上的投影,告诉操作要等待输入-在第一部分中:
(1b;)value@
等待输入t
-如果值操作成功,则返回(1b;correctOutput)
,即执行投影。
如果失败,错误将传递给
@[(1b;)c@;;(0b;)::]
基本上是同一件事,但是它使用catch函数value
代替了c
。这是一个投影,它采用之前从失败值传递来的输入,然后应用与上述相同的操作。错误的输出将传递到全局null ::
。
如果try或catch成功,则确保数据结构r的前导值为1b,如果都失败,则数据结构的r为前导0b。
然后运行finally
函数,如果出现两次失败,返回结果是成功的答案或抛出错误。
使用与Rahul答案相似的定义的示例:
q)tryfunc
{x+y}
q)workingcatchfunc
{show "catch";100}
q)brokencatchfunc
{show "catch";1+`a}
q)finallyfunc
{show"finally"}
q)tcf[(tryfunc;1;1);workingcatchfunc;finallyfunc]
"finally"
2
q)tcf[(tryfunc;1;`a);workingcatchfunc;finallyfunc]
"catch"
"finally"
100
q)tcf[(tryfunc;1;`a);brokencatchfunc;finallyfunc]
"catch"
"finally"
'type
这也适用于带有任意数量参数的函数:
q)tcf[(monot;1);brokencatchfunc;finallyfunc]
"finally"
10
q)tcf[(monot;`);brokencatchfunc;finallyfunc]
"catch"
"finally"
'type
答案 1 :(得分:1)
KDB中没有finally
块。在KDB中使功能更接近此功能的一种方法是为final
块编写一个函数,然后在try和catch中都调用它。这不能保证此功能将始终执行,但可以涵盖大多数情况。
q)finally:{show "finally"}
q)try:{show "try"; show x+y;finally[]}
q)catch:{show "catch"; finally[]}
q).[try;1 2;catch]
Output:
"try"
3
"finally"
现在,在try and catch中调用finally
函数很重要。调用顺序可能会更改行为。我的建议是最后调用它,并始终从finally
函数返回结果。如果try or catch
函数有任何返回值,则将该值传递给finally
函数。这样可以减少出错的机会,简化代码,并消除其他开销,例如呼叫排序问题。
来自try
块的返回值示例:
q) finally:{show "finally"; :x}
q) try:{show "try";r:x+y;finally r}
q) catch:{show "catch"; finally[]}
q) .[tyr;1 2;catch]
Output
"try"
"finally"
3