如何从Postgres表中的ltree删除特定标签?

时间:2012-12-26 05:06:52

标签: sql postgresql tree sql-update postgresql-9.1

如何从Postgres表中的ltree删除特定标签?我有一张桌子:

test(sno integer, path ltree, userid integer)

如果我在查询中将userid作为参数传递,它将删除所有路径中的所有匹配标签。怎么做到这一点?

测试表:

CREATE TABLE tbl (sno int,  path ltree, userid int);
INSERT INTO tbl (sno,  path, userid)
VALUES
 (1, '123',             123)
,(2, '123.101',         123)
,(3, '123.101.103',     123)
,(4, '123.101.103.105', 123)
,(5, '123.101.103.107', 123)
,(6, '123.102.104.106', 123)
,(7, '123.102.104.108', 123)
,(8, '123.102.104',     123)
,(9, '123.102',         123);

示例:如果我传递用户ID,它将从表中的所有路径中删除所有此用户ID。是否可以直接执行此操作?或者我应该使用路径替换功能更新路径吗?

我从PHP尝试以下select查询,它返回以下错误。相同的查询在phpPgAdmin sql查询中正常工作。)

查询:

$selectPathq=pg_query($con,"select path from myschema.test where path @ '101'")
             or die('could not connect: '. pg_last_error($con));

错误:

  

无法连接:ERROR:运算符不存在:myschema.ltree @ unknown at character 63提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。

1 个答案:

答案 0 :(得分:4)

修复错误

要使用数据类型ltree及相关功能,您需要安装额外的模块ltree

默认情况下,会在架构public中安装其他模块。如果search_path的当前设置不包含架构public,则找不到ltree运算符。您的错误消息提示了这个方向:

  

错误:运算符不存在:myschema.ltree @ unknown at character 63

验证,模式限定ltree运算符@

SELECT path FROM tbl WHERE path operator(public.@) '101';

现在有用吗?
如果这是问题的根源,您还可以正确设置search_path。检查:

SHOW search_path;

设置为:

SET search_path = public; -- add more schemas as needed

The manual about search_path.

更新路径

如果我正确阅读了您的问题,并且您想从所有行的路径中删除某个项目:

UPDATE tbl t
SET    path = nu.path
FROM (
   WITH x AS (
      SELECT sno, path, index(path, '123') AS i
      FROM   tbl
      WHERE  path ~ '*.123.*'
      )
   SELECT sno
         ,subpath(path, 0, i)
          || CASE WHEN nlevel(path) > i+1 THEN subpath(path, i+1)
                                          ELSE '' END AS path
   FROM x
   ) nu
WHERE nu.sno = t.sno;

这将为您留下一条只有123的空路径。您可以将其置于触发器AFTER DELETE中以清除所有行中的某个项目。