Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 找出基于表值的模式_Sql_Django_Postgresql_Database Connection_Postgresql 9.2 - Fatal编程技术网

Sql 找出基于表值的模式

Sql 找出基于表值的模式,sql,django,postgresql,database-connection,postgresql-9.2,Sql,Django,Postgresql,Database Connection,Postgresql 9.2,我的数据库根据客户机划分为模式(即:每个客户机都有自己的模式,具有相同的数据结构) 我还碰巧有一个外部操作,它不知道应该以哪个模式为目标。它来自系统的另一个部分,它没有客户机的概念,也不知道它在哪个客户机集中运行。在处理它之前,我必须找出该请求需要以哪个模式为目标 为了找到正确的模式,我必须找出哪个保存了具有特定唯一ID(字符串)的记录R 根据我的理解,以下是 SET search_path TO schema1,schema2,schema3,... 将只查看schema1中的表(或与该表匹

我的数据库根据客户机划分为模式(即:每个客户机都有自己的模式,具有相同的数据结构)

我还碰巧有一个外部操作,它不知道应该以哪个模式为目标。它来自系统的另一个部分,它没有客户机的概念,也不知道它在哪个客户机集中运行。在处理它之前,我必须找出该请求需要以哪个模式为目标

为了找到正确的模式,我必须找出哪个保存了具有特定唯一ID(字符串)的记录
R

根据我的理解,以下是

SET search_path TO schema1,schema2,schema3,...
将只查看schema1中的表(或与该表匹配的第一个架构),而不会进行全局搜索


有没有一种方法可以让我在所有模式中进行全局搜索,或者我只需要使用for循环并一次遍历所有模式?

您必须遍历所有名称空间。您可以从
pg.*
系统目录中获得大量此类信息。理论上,您应该能够在请求时解析client->schema映射,而无需与数据库通信,因此您进行的第一个SQL调用是:

SET search_path = client1,global_schema;
你可以用这个。(一定要考虑)./P> 考虑一下这个小演示:

CREATE SCHEMA master;  -- no access of others ..

CREATE SEQUENCE master.myseq;  -- global sequence to have globally unique id
CREATE table master.tbl (
  id int primary key DEFAULT nextval('master.myseq')
, foo text);

CREATE SCHEMA x;
CREATE table x.tbl() INHERITS (master.tbl);
INSERT INTO  x.tbl(foo) VALUES ('x');

CREATE SCHEMA y;
CREATE table y.tbl() INHERITS (master.tbl);
INSERT INTO  y.tbl(foo) VALUES ('y');


SELECT * FROM x.tbl;  -- returns 'x'
SELECT * FROM y.tbl;  -- returns 'y'
SELECT * FROM master.tbl;  -- returns 'x' and 'y' <-- !!

-- clean it all up:
-- DROP SCHEMA x, y, master CASCADE;
结果:

id | foo | table_name
---+-----+-----------
2  | y   | y.tbl
您可以从
tableoid
派生源架构,最好是直接使用
tableoid
查询系统目录。(显示的名称取决于
search\u path
的设置)


这也比在许多单独的表中循环快得多。

虽然我认为如果您可以重新构造表,Erwin的解决方案可能更可取,但另一种不需要任何架构更改的方法是编写PL/PgSQL函数,该函数使用基于系统目录信息的动态SQL扫描表

鉴于:

CREATE SCHEMA a;
CREATE SCHEMA b;

CREATE TABLE a.testtab ( searchval text );
CREATE TABLE b.testtab (LIKE a.testtab);

INSERT INTO a.testtab(searchval) VALUES ('ham');
INSERT INTO b.testtab(searchval) VALUES ('eggs');
以下PL/PgSQL函数搜索包含名为
\u tabname
的表的所有架构,以查找
\u colname
中等于
\u value
的值,并返回第一个匹配的架构

CREATE OR REPLACE FUNCTION find_schema_for_value(_tabname text, _colname text, _value text) RETURNS text AS $$
DECLARE
    cur_schema text;
    foundval integer;
BEGIN
    FOR cur_schema IN 
      SELECT nspname 
      FROM pg_class c 
      INNER JOIN pg_namespace n ON (c.relnamespace = n.oid) 
      WHERE c.relname = _tabname AND c.relkind = 'r'
    LOOP
      EXECUTE 
        format('SELECT 1 FROM %I.%I WHERE %I = $1', 
            cur_schema, _tabname, _colname
        ) INTO foundval USING _value;
      IF foundval = 1 THEN
        RETURN cur_schema;
      END IF;
    END LOOP;
    RETURN NULL;
END;
$$ LANGUAGE 'plpgsql';
如果没有匹配项,则返回null。如果有多个匹配项,结果将是其中一个,但无法保证是哪一个。如果要按字母顺序返回(比如)第一个,请在模式查询中添加一个
orderby
子句。如果要返回所有匹配项,还可以对函数进行简单修改,以返回
setoftext
returnnext cur\u schema

regress=# SELECT find_schema_for_value('testtab','searchval','ham');
 find_schema_for_value 
-----------------------
 a
(1 row)

regress=# SELECT find_schema_for_value('testtab','searchval','eggs');
 find_schema_for_value 
-----------------------
 b
(1 row)

regress=# SELECT find_schema_for_value('testtab','searchval','bones');
 find_schema_for_value 
-----------------------

(1 row)

顺便说一下,如果需要,您可以在不继承的情况下重用表定义,而且您确实应该这样做。使用通用复合数据类型:

CREATE TYPE public.testtab AS ( searchval text );
CREATE TABLE a.testtab OF public.testtab;
CREATE TABLE b.testtab OF public.testtab;
在这种情况下,它们共享相同的数据类型,但不共享任何数据;或通过

CREATE TABLE public.testtab ( searchval text );
CREATE TABLE a.testtab (LIKE public.testtab);
CREATE TABLE b.testtab (LIKE public.testtab);

在这种情况下,它们在创建后彼此完全不连接。

据我所知,您要做的是搜索通过多个模型输入的字符串?像lets say用户输入“hello”,您希望在lets say模型中搜索此hello:汽车、公共汽车、自行车。我理解你的问题了吗?@Jonathanq:不,每个模式都是相同的,我想在同一个模型中查找数据,只是在不同的模式中:所以schema1.cars、schema2.cars、schema3.cars等等听起来很复杂。django处理PostgreSQL继承的能力如何?我不是django方面的专家,但这应该一点也不复杂。事实上,如果在许多模式中都有相同的表,则可以大大简化
CREATE
脚本。需要明确的是:所有CREATE命令只能执行一次。但这很清楚,对吗?我忘记添加的内容(现在添加):如何识别源表。
CREATE TYPE public.testtab AS ( searchval text );
CREATE TABLE a.testtab OF public.testtab;
CREATE TABLE b.testtab OF public.testtab;
CREATE TABLE public.testtab ( searchval text );
CREATE TABLE a.testtab (LIKE public.testtab);
CREATE TABLE b.testtab (LIKE public.testtab);