我正在尝试声明要在MonetDB中执行的查询字符串。如果可能,文档不清楚,但其他引擎允许此功能(例如MySQL和MS SQL Sever)。尝试以下
execute 'select * from tables';
失败并显示消息
Error: syntax error, unexpected STRING, expecting IDENT or sqlINT
这背后的原因是我需要声明一个变量模式名称,这样我就可以通过以下方式执行查询:
declare s varchar(32);
set s = 'the_schema';
execute 'select * from ' || the_schema || '.the_table';
如果您在MonetDB中甚至可以这样做,或者您有一些提示,请告诉我。我尝试使用MonetDB文档中给出的预准备语句 - 但以下代码无法执行
prepare 'select * from ' || the_schema || '.the_table';
因为prepare
需要实际查询,而不是字符串。
修改
我想只使用SQL存储函数来实现这一点。我必须直接执行SQL函数,并且在将它们发送到MonetDB服务器之前,没有中间的Java / PHP / etc脚本可以动态构建SQL。因此,我应该创建一个这样的函数:
create function getData( dataSchema varchar(32) )
returns bigint
begin
declare query varchar(128);
set query = 'select count(*) from ' || dataSchema || '.the_table';
return( execute query );
end;
我的功能比这更复杂,还有其他表甚至功能。问题是函数属于一个模式,而数据表属于另一个模式,这在“编译”时间内是未知的。
答案 0 :(得分:2)
不幸的是,MonetDB不支持这一点。
如果构造查询的唯一不同部分是值,则可以尝试PREPARE:
sql>PREPARE SELECT * FROM foo WHERE id = ?;
execute prepared statement using: EXEC 13(...)
sql>EXEC 13(22);
但是例如写FROM ?
是不可能的。对于那种事情,唯一的选择是进行字符串连接客户端。
答案 1 :(得分:1)
这应该被认为是一个hack,但是python UDF执行SQL查询的能力通过预定义的_conn
处理程序实现了这一点:
create or replace function tableLen( schema string, name string )
returns bigint
language python {
query = 'select count(*) as c from ' + schema + '.' + name + ';'
result = _conn.execute(query)
return result['c']
};
然后
sql>select tableLen('sys','tables');
+------+
| L2 |
+======+
| 101 |
+------+
1 tuple (12.535ms)
更一般地说,使用这个技巧你可能会有一个类似的功能,你可以用这种方式进行任何查询:
sql> select myExecute('SELECT ..... ');
请注意,不是可能的,因为您需要为该函数定义确切的返回类型,这当然与通用查询不匹配。