如何在 MonetDB 中执行查询字符串

How to execute a query string in MonetDB

我正在尝试声明一个查询字符串以在 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 函数,并且在 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;

我的函数比这个复杂,还有其他的表,甚至还有函数。问题是函数属于一个模式,数据表属于另一个模式,这在 'compile' 时间是未知的。

遗憾的是,MonetDB 不支持这一点。

如果构造查询的唯一变化部分是值,您可以尝试 PREPARE:

sql>PREPARE SELECT * FROM foo WHERE id = ?;
execute prepared statement using: EXEC 13(...)
sql>EXEC 13(22);

但是不可能写成FROM ?。对于那种事情,唯一的选择是在客户端进行字符串连接。

这应该被认为是一种 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 ..... ');

请注意,这 不会 成为可能,因为您需要为该函数定义确切的 return 类型,这当然不会匹配一般查询。