相关疑难解决方法(0)

如何修改新PostgreSQL JSON数据类型中的字段?

使用postgresql 9.3我可以选择JSON数据类型的特定字段,但是如何使用UPDATE修改它们?我在postgresql文档中或在线任何地方都找不到任何这样的例子.我试过了明显的事:

postgres=# create table test (data json);
CREATE TABLE
postgres=# insert into test (data) values ('{"a":1,"b":2}');
INSERT 0 1
postgres=# select data->'a' from test where data->>'b' = '2';
 ?column?
----------
 1
(1 row)
postgres=# update test set data->'a' = to_json(5) where data->>'b' = '2';
ERROR:  syntax error at or near "->"
LINE 1: update test set data->'a' = to_json(5) where data->>'b' = '2...
Run Code Online (Sandbox Code Playgroud)

postgresql json postgresql-9.3 postgresql-json

199
推荐指数
10
解决办法
18万
查看次数

如何在PostgreSQL中的函数内返回SELECT的结果?

我在PostgreSQL中有这个功能,但我不知道如何返回查询结果:

CREATE OR REPLACE FUNCTION wordFrequency(maxTokens INTEGER)
  RETURNS SETOF RECORD AS
$$
BEGIN
    SELECT text, count(*), 100 / maxTokens * count(*)
    FROM (
        SELECT text
    FROM token
    WHERE chartype = 'ALPHABETIC'
    LIMIT maxTokens
    ) as tokens
    GROUP BY text
    ORDER BY count DESC
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

但我不知道如何在PostgreSQL函数中返回查询结果.

我发现返回类型应该是SETOF RECORD,对吗?但是返回命令不对.

这样做的正确方法是什么?

sql postgresql return return-type plpgsql

92
推荐指数
2
解决办法
14万
查看次数

为PostgreSQL中的记录变量动态传递列名

使用PostgreSQL,第一条记录的表中的列值存储在记录变量中.例如:让变量为:recordvar

recordvar.columnname
Run Code Online (Sandbox Code Playgroud)

给出指定列名的值.我将columname在变量中定义:

var := columnname
Run Code Online (Sandbox Code Playgroud)

在地方columnname,如果我与变量如更换recordvar.var,这是行不通的.

请让我知道如何处理这种情况.以下是示例代码:

CREATE OR REPLACE FUNCTION getrowdata(id numeric, table_name character varying)
RETURNS SETOF void AS
$BODY$ 
DECLARE

srowdata record;
reqfield character varying;
value numeric;


BEGIN

RAISE NOTICE 'id: %',id; 
reqfield:= 'columnname';

EXECUTE 'select * from datas.'||table_name||' WHERE id = '||id into srowdata;

RAISE NOTICE 'srowdata: %',srowdata; 

RAISE NOTICE 'srowdatadata.columnname: %',srowdata.columnname;

value:= srowdata.reqfield;

RAISE NOTICE 'value: %',value;


END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
Run Code Online (Sandbox Code Playgroud)

postgresql types dynamic-sql plpgsql hstore

17
推荐指数
1
解决办法
2万
查看次数

IMMUTABLE,STABLE和VOLATILE关键字如何影响函数的行为?

我们编写了一个get_timestamp()定义为的函数

CREATE OR REPLACE FUNCTION get_timestamp()
  RETURNS integer AS
$$
SELECT (FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 10) - 13885344000)::int;
$$
LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)

这在INSERT和UPDATE上用于输入或编辑数据库记录中已创建和已修改字段中的值.但是,我们发现连续添加或更新记录时它返回的值相同.

在检查pgAdmin III中的函数时,我们注意到在运行SQL来构建函数时,在LANGUAGE SQL语句之后注入了关键字IMMUTABLE.该文件指出默认是挥发性的(如果一个都没有出现,VOLATILE是默认的假设),所以我不知道为什么IMMUTABLE注射,然而,改变这种稳定解决了重复值的问题.

注意:如接受的答案中所述,IMMUTABLE永远不会被pgAdmin或Postgres添加到函数中,并且必须在开发期间添加.

我猜测正在发生的事情是这个函数正在被评估并且结果被缓存用于优化,因为它被标记为IMMUTABLE指示Postgres引擎在给定相同(空)参数列表的情况下返回值不应该改变.但是,当在触发器中未使用时,直接在INSERT语句中使用时,该函数将返回一个不同的值五次,然后再返回相同的值.这是由于某些优化算法会出现类似"如果在会话中多次使用IMMUTABLE函数5次,请将结果缓存以供将来调用"?

关于如何在Postgres函数中使用这些关键字的任何说明将不胜感激.对于我们来说STABLE是正确的选择,因为我们在触发器中使用了这个函数,或者还有更多要考虑的东西,例如文档说:

(对于希望查询当前命令修改的行的AFTER触发器不合适.)

但我并不清楚原因.

database postgresql timestamp function volatility

8
推荐指数
1
解决办法
5697
查看次数

循环通过RECORD列

我需要RECORD按键/索引遍历类型项,就像我可以使用其他编程语言中的数组结构一样.

例如:

DECLARE
    data1    record;
    data2    text;
...
BEGIN
...
FOR data1 IN
    SELECT
        *
    FROM
        sometable
LOOP

    FOR data2 IN
        SELECT
            unnest( data1 )   -- THIS IS DOESN'T WORK!
    LOOP
        RETURN NEXT data1[data2];   -- SMTH LIKE THIS
    END LOOP;

END LOOP;
Run Code Online (Sandbox Code Playgroud)

postgresql loops for-loop record plpgsql

6
推荐指数
2
解决办法
2万
查看次数

Postgresql通用触发器函数?

我是 Postgresql 新手,所以如果我的问题没有意义,请原谅。

我正在尝试找到一种方法将我的数据库结构迁移到Postgresql,特别是,我发现函数非常方便,并且希望使我的众多触发器更容易编写。

在我的数据库中,我使用标准last_modifiedlast_modified_by字段来跟踪更改。我还使用带有增量序列的标准主键。

有内置语法可将序列链接到主键 ID,但由于last_modified无论如何我都必须为字段编写触发器,所以我想知道是否可以有一个通用函数来一次更新所有内容。

示例:表ANIMAL有字段AMIMAL_ID(主键,带有序列SEQ_ANIMAL)、字段LAST_MODIFIEDLAST_MODIFIED_BY

同样,我有一个PLANT包含字段PLANT_ID(主键,带有序列SEQ_PLANT)、字段LAST_MODIFIED等等的表LAST_MODIFIED_BY

我想创建一个通用函数,在我需要创建的 4 个触发器中调用。我希望得到这样的东西:

插入函数之前:

CREATE FUNCTION TRIGGER_BI(p_pkField text, p_Sequence text) RETURNS TRIGGER AS $$
DECLARE
        curtime timestamp := now();
BEGIN
    NEW.LAST_UPDATED := curtime;
    NEW.LAST_UPDATED_BY := current_user;
    NEW.p_pkField := nextval(p_Sequence);
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
Run Code Online (Sandbox Code Playgroud)

更新前功能:

CREATE FUNCTION TRIGGER_BU() RETURNS TRIGGER AS $$
DECLARE …
Run Code Online (Sandbox Code Playgroud)

postgresql triggers primary-key

6
推荐指数
1
解决办法
5517
查看次数

如何创建PostgreSQL分区序列?

是否有一种简单的(即非hacky)和无竞争条件的方法来在PostgreSQL中创建分区序列.例:

在问题中使用正常序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 3     |
| 2          | 4     |
Run Code Online (Sandbox Code Playgroud)

在问题中使用分区序列:

| Project_ID | Issue |
| 1          | 1     |
| 1          | 2     |
| 2          | 1     |
| 2          | 2     |
Run Code Online (Sandbox Code Playgroud)

postgresql partitioning sequence

5
推荐指数
1
解决办法
2400
查看次数

PL/pgSQL:更新触发器中 N 列的一般方法?

我正在尝试创建一个函数,该函数将采用通用表并将 N 列转换为大写。我没有找到此类问题的解决方案,但我能够提出以下建议:

create or replace function uc_on_insert()
returns trigger as
$$
declare
p_tbl varchar = TG_TABLE_NAME;
p_sch varchar = TG_TABLE_SCHEMA;
i varchar;
begin
    for i in 

    (select column_name
    from  INFORMATION_SCHEMA.COLUMNS
    where 1=1
    and table_name ilike p_tbl
    and table_schema ilike p_sch
    and data_type ='character varying')

    loop
           execute 'new.' || i || ' = upper(new.' || i || ');';
       return new;
    end loop;

end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

我目前收到此错误:

ERROR:  syntax error at or near "new"
LINE 1: new.c1 = upper(new.c1);
        ^ …
Run Code Online (Sandbox Code Playgroud)

postgresql triggers types dynamic-sql plpgsql

3
推荐指数
1
解决办法
1807
查看次数

unaccent()阻止Postgres中的索引使用

我想从导入PostgreSQL 9.3.5的OpenStreetMap数据库中检索具有给定名称的方法,操作系统是Win7 64位.为了有点容错,我使用了Postgres的unaccent扩展.

我的查询如下:

SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower(unaccent('unaccent','Weststrasse'))
Run Code Online (Sandbox Code Playgroud)

查询计划:

Seq Scan on ways  (cost=0.00..2958579.31 rows=122 width=465)
  Filter: (lower((tags -> 'name'::text)) ~~ lower(unaccent('unaccent'::regdictionary, 'Weststrasse'::text)))
Run Code Online (Sandbox Code Playgroud)

奇怪的是,此查询使用顺序扫描方式,尽管索引存在于lower(tags->'name'):

CREATE INDEX ways_tags_name ON germany.ways (lower(tags -> 'name'));
Run Code Online (Sandbox Code Playgroud)

一旦我从查询中删除unaccent,Postgres就会使用索引:

SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower('Weststrasse')
Run Code Online (Sandbox Code Playgroud)

查询计划:

Index Scan using ways_tags_name on ways  (cost=0.57..495.43 rows=122 width=465)
  Index Cond: (lower((tags -> 'name'::text)) = 'weststrasse'::text)
  Filter: (lower((tags -> 'name'::text)) ~~ 'weststrasse'::text)
Run Code Online (Sandbox Code Playgroud)

为什么无法防止Postgres使用索引?在我看来,这没有意义,因为在执行实际查询之前,应该已经完全知道unaccent(变音符号删除等)的结果.所以Postgres应该能够使用索引.使用unaccent时如何避免seq扫描?

sql postgresql indexing unaccent openstreetmap

3
推荐指数
1
解决办法
2974
查看次数

PostgreSQL plpgsql-变量列名

我正在创建一个触发器,该触发器为列使用动态名称

NEW.name:=2222; -- works fine !
Run Code Online (Sandbox Code Playgroud)

dynamic_column:='name';
EXECUTE '$1.'||dynamic_column||':=2222 ' USING NEW; -- raises error
Run Code Online (Sandbox Code Playgroud)

给出一个错误:

错误:“ $ 1”或附近的语法错误LINE 1:$ 1.name:= 2222

postgresql plpgsql

3
推荐指数
3
解决办法
3234
查看次数

使用%TYPE在PostgreSQL中声明复合类型的变量

问题:如何在存储函数中声明相同类型的变量参数?

简单的答案是使用%TYPE,这有效:

CREATE OR REPLACE FUNCTION test_function_1(param1 text)
  RETURNS integer AS
$BODY$ 
DECLARE
    myVariable param1%TYPE;
BEGIN
    return 1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

但问题是何时param1是复合类型:

CREATE TYPE comp_type as
(
    field1 text
)

CREATE OR REPLACE FUNCTION test_function_2(param1 comp_type)
  RETURNS integer AS
$BODY$ 
DECLARE
    myVariable param1%TYPE;
BEGIN
    return 1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Run Code Online (Sandbox Code Playgroud)

这不起作用:

ERROR: type comp_type does not exist [SQL State=42704]
Run Code Online (Sandbox Code Playgroud)

那么当param1复合型时我该怎么办?

(注意:myVariable comp_type因为我的功能稍微复杂一点, …

postgresql polymorphism types stored-procedures plpgsql

2
推荐指数
1
解决办法
6492
查看次数

在PL / pgSQL中动态执行查询

我已经找到了我要在Oracle和SQL Server上解决的问题的解决方案(我认为),但是似乎无法将其转换为Postgres解决方案。我正在使用Postgres 9.3.6。

这个想法是为了生成用于分析目的的有关表内容的“元数据”。这只能通过让每一列都运行查询来找出(例如...)最小/最大/计数值等来完成(AFAIK)。为了使过程自动化,最好让数据库生成查询,然后执行查询。

使用示例salesdata表,我可以使用以下代码段为每列生成一个选择查询,并返回min()值:

SELECT 'SELECT min('||column_name||') as minval_'||column_name||' from salesdata '  
FROM information_schema.columns 
WHERE table_name = 'salesdata'
Run Code Online (Sandbox Code Playgroud)

优点是,无论列数如何,数据库都会生成代码。现在,我想到了无数个地方来存储这些查询,这些查询可以是某种变量,也可以是表列,其想法是执行这些查询。我想将生成的查询存储在变量中,然后使用EXECUTE(或EXECUTE IMMEDIATE)语句执行它们,这是此处采用的方法(请参见右窗格),但是Postgres不会让我在函数外部声明变量,因此我一直在抓挠我对如何将它们组合在一起,无论是什至是遵循的方向,也许还有更简单的东西。

您有任何指点吗,由于其他问题,我目前正在尝试类似的方法,但不知道我是否朝着正确的方向前进:

CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
DECLARE
    dyn_sql text; 
BEGIN            
dyn_sql := SELECT 'SELECT min('||column_name||') from salesdata'    
    FROM information_schema.columns 
    WHERE table_name = 'salesdata';
execute dyn_sql
END
$$ LANGUAGE PLPGSQL;    
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql aggregate-functions dynamic-queries

2
推荐指数
1
解决办法
1万
查看次数

将表和更改日志合并到PostgreSQL中的视图中

我的PostgreSQL数据库包含一个用于存储已注册实体实例的表.此表格通过电子表格上传填充.Web界面允许操作员修改所呈现的信息.但是,原始数据不会被修改.所有的改变都存储在一个单独的表changes与列unique_id,column_name,valueupdated_at.

更改完成后,首先查询原始表,然后查询更改表(使用实例ID和最新更改日期,按列名称分组),将其呈现给操作员.这两个结果在PHP中合并,并在Web界面上显示.这是执行任务的一种相当严格的方式,我想将所有逻辑保留在SQL中.

我可以使用以下查询轻松选择表的最新更改:

SELECT fltr_chg.unique_id, fltr_chg.column_name, chg_val.value 
FROM changes AS chg_val
JOIN ( 
      SELECT chg_rec.unique_id, chg_rec.column_name, MAX( chg_rec.updated_at )
      FROM information_schema.columns AS source
      JOIN changes AS chg_rec ON source.table_name = 'instances'
                             AND source.column_name = chg_rec.column_name
      GROUP BY chg_rec.unique_id, chg_rec.column_name
     ) AS fltr_chg ON fltr_chg.unique_id = chg_val.unique_id
                  AND fltr_chg.column_name = chg_val.column_name;
Run Code Online (Sandbox Code Playgroud)

instances表中选择条目同样简单:

SELECT * FROM instances;
Run Code Online (Sandbox Code Playgroud)

现在,如果只有一种方法可以转换前一个结果并将结果值替换为后者,基于unique_idcolumn_name,并且仍将结果保留为表格,则问题将得到解决.这可能吗?

我确信这不是最罕见的问题,而且很有可能,某些系统会以类似的方式跟踪数据的变化.如果不是通过上述方法之一(当前和寻求的解决方案),他们如何将它们应用于数据?

php postgresql dynamic-sql crosstab plpgsql

1
推荐指数
1
解决办法
1234
查看次数