我试图编写一个语句来检查表是否包含行:
toHaveBeenCalledWith
如果想的话,我会将表名传递给:$ 1
我收到以下错误消息:
语法错误在“$ 1”或附近
我的陈述有什么问题?
答案 0 :(得分:0)
您可以从系统目录中获取此信息比查询表本身更便宜,更快。
CREATE OR REPLACE FUNCTION table_empty(tablename text, tableschema text)
RETURNS BOOLEAN AS $$
BEGIN
RETURN (SELECT CASE WHEN (reltuples::integer > 0)
THEN false
ELSE (SELECT count(*) = 0
FROM quote_ident(tableschema || '.' || tablename) )
END
FROM pg_namespace nc
JOIN pg_class c
ON nc.oid = c.relnamespace
WHERE relname=tablename AND nc.nspname = tableschema);
END;
$$
LANGUAGE plpgsql;
SELECT table_empty('pg_class','pg_catalog');
table_empty
-----------
f
1 row
答案 1 :(得分:0)
base driver仅执行服务器级支持的基本查询格式,不支持动态表名。
这意味着表名需要在您身边进行转义。您可以手动执行此操作,也可以依赖支持它的库,例如下面使用pg-promise的示例:
db.one('SELECT count(*) FROM $1:name', table, a => +a.count)
.then(count => {
// count = the integer record count
})
.catch(error => {
// either table doesn't exist, or a connectivity issue
});
或者,使用Named Parameters:
db.one('SELECT count(*) FROM ${table:name}', {table}, a => +a.count)
.then(count => {
// count = the integer record count
})
.catch(error => {
// either table doesn't exist, or a connectivity issue
});
过滤器:name
告诉格式化引擎将其作为SQL名称转义。如果您愿意,此过滤器还有较短的版本~
,即$1~
或${table~}
。
此外,我们正在使用方法one,因为该查询总是希望返回单行结果。
答案 2 :(得分:0)
你不能用准备好的声明来做。使用柯克建议的功能。唯一的区别是,选择第一行可能更安全,例如:
t=# create or replace function tempty(tn text) returns boolean as
$$
declare
c int;
begin
execute format('select 1 from %I limit 1',tn) into c;
return NOT coalesce(c,0) > 0;
end;
$$ language plpgsql
;
CREATE FUNCTION
t=# create table empty(i int);
CREATE TABLE
t=# select tempty('empty');
tempty
--------
t
(1 row)
t=# select tempty('pg_class');
tempty
--------
f
(1 row)
docs do not say直接传递给execute
预处理语句的值不能是标识符,但是在标识符不能提及的任何地方都提到它们,例如:
通用计划假设提供给EXECUTE的每个值都是其中之一 列的不同值和列值是统一的 分布。
($ 1是列值,有或没有某些属性。)