我从一个示例中复制了一些用于访问sqlite数据库的代码。它使用代理来获取返回的行:
check_db (input_line: STRING)
local
df_db: SQLITE_DATABASE
df_db_query: SQLITE_QUERY_STATEMENT
test_val: STRING
do
test_val := "whatever"
create df_db.make_open_read_write ("Large.db")
create df_db_query.make ("SELECT * FROM test_table WHERE test_val =%
% :TEST_VAL%
% ;", df_db)
check df_db_query_is_compiled: df_db_query.is_compiled
end
df_db_query.execute_with_arguments (agent (returned_row: SQLITE_RESULT_ROW): BOOLEAN
do
if returned_row.is_null (1) then
insert_into_db
end
end,
<< create {SQLITE_STRING_ARG}.make (":TEST_VAL", test_val) >>)
end -- check_db
我遇到的问题是我想将input_line传递给过程insert_into_db。 execute_with_arguments使用的内联过程不能查看其范围之外的任何变量,但我认为必须有一种方法可以向其传递一个额外的参数?我尝试过的所有内容都拒绝使用语法错误进行编译。
在这种情况下,我只是想添加一个数据库条目,如果它还不存在,但我可以很容易地看到我想将返回的行和一些额外的数据发送到另一个程序的情况,所以它必须是可行的。
答案 0 :(得分:1)
正如您正确指出的那样,目前,Eiffel中的局部变量不会自动传递到内联代理。解决方案是向内联代理添加显式的形式参数,并将相应的实际参数传递给它。
示例中的内联代理可以按如下方式进行调整(为简洁起见,省略了带有参数input_line
的外部上下文):
agent (returned_row: SQLITE_RESULT_ROW; s: STRING): BOOLEAN
do
-- `s` is attached to `input_line` here.
if returned_row.is_null (1) then
insert_into_db
end
end (?, input_line)
除了将获得s
值的正式参数input_line
之外,您还可以看到实际参数(?, input_line)
的明确列表。问号表示一个开放的参数,它将像execute_with_arguments
一样传递给代理。 input_line
代表一个封闭的论点。
当列表没有关闭的参数时,如原始代码中那样,它可以省略。但是,可以在原始代码中的内联代理的关键字(?)
之后编写end
,以完全明确。