标签: plpgsql

转换测量单位

希望为一系列物质计算最合适的计量单位,其中物质以不同(但兼容)的单位体积给出。

单位换算表

单位转换表存储各种单位以及这些单位之间的关系:

id  unit          coefficient                 parent_id
36  "microlitre"  0.0000000010000000000000000 37
37  "millilitre"  0.0000010000000000000000000 5
 5  "centilitre"  0.0000100000000000000000000 18
18  "decilitre"   0.0001000000000000000000000 34
34  "litre"       0.0010000000000000000000000 19
19  "dekalitre"   0.0100000000000000000000000 29
29  "hectolitre"  0.1000000000000000000000000 33
33  "kilolitre"   1.0000000000000000000000000 35
35  "megalitre"   1000.0000000000000000000000 0
Run Code Online (Sandbox Code Playgroud)

按系数排序表明将parent_id子单元与其上级数值联系起来。

可以使用以下命令在 PostgreSQL 中创建此表:

CREATE TABLE unit_conversion (
  id serial NOT NULL, -- Primary key.
  unit text NOT NULL, -- Unit of measurement name.
  coefficient numeric(30,25) NOT NULL DEFAULT 0, -- Conversion value.
  parent_id integer …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql postgresql-9.1 number-formatting

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

如何仅根据字段名称访问 NEW 或 OLD 字段?

我正在编写一个验证触发器。触发器必须验证数组的总和是否等于另一个字段。由于我有许多此验证的实例,因此我想编写一个过程并创建多个触发器,每个触发器都有一组不同的要检查的字段。

例如,我有以下架构:

CREATE TABLE daily_reports(
     start_on date
   , show_id uuid
   , primary key(start_on, show_id)

     -- _graph are hourly values, while _count is total for the report
   , impressions_count bigint not null
   , impressions_graph bigint[] not null

   -- interactions_count, interactions_graph
   -- twitter_interactions_count, twitter_interactions_graph
);
Run Code Online (Sandbox Code Playgroud)

验证必须确认impressions_count = sum(impressions_graph)

我被卡住了,因为我不知道如何NEW从 plpgsql 中动态访问一个字段:

CREATE FUNCTION validate_sum_of_array_equals_other() RETURNS TRIGGER AS $$
DECLARE
  total bigint;
  array_sum bigint;
BEGIN
  -- TG_NARGS = 2
  -- TG_ARGV[0] = 'impressions_count'
  -- TG_ARGV[1] = 'impressions_graph'

  -- How …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger plpgsql composite-types

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

分块删除活动表上的多行 - 无需锁定太长时间(PostgreSQL 9.3)

我是 postgres 的新手,

我在实时服务器上有一个 2000 万行的表 - 我需要删除大部分行但不是全部。我想这样做而不影响访问此表的其他读/写进程(非常频繁)。

我有一种方法可以一次删除大约 100-400K 行块。在每次删除之间,我想让查询休眠 - 以便其他操作可以有机会访问此表。

我有代码,但我相信这个版本,它在查询运行的整个时间(所有睡眠)都锁定表。我怎样才能在进程休眠时真正释放表?谢谢!!

到目前为止我的代码:

CREATE SEQUENCE tmp_sq increment by 1 minvalue 1 maxvalue 53 start with 1;

DO $$

DECLARE 
w_counter integer;

BEGIN
w_counter := (SELECT nextval('tmp_sq')); 

  while w_counter < 53 loop
    raise notice 'Value: %', w_counter ;

    w_counter := (SELECT nextval('tmp_sq')); 

-- this way of breaking up the delete into chunks works for my table because of dates.
    delete from table_a where date_part('week',my_date) = w_counter;

    raise notice ' …
Run Code Online (Sandbox Code Playgroud)

postgresql delete plpgsql

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

在 PL/pgSQL 中声明表类型的变量

我想知道是否有办法在 PL/pgSQL 中声明表类型的变量来保存查询结果?例如,我如何表达如下内容:

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2
Run Code Online (Sandbox Code Playgroud)

我查看了 return next 构造,但它似乎只能处理返回值。

postgresql stored-procedures plpgsql

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

将 RECORD 插入触发器函数中的表中

我想在触发器的表中插入一个 RECORD 数据类型变量(新变量)。SQL 会是什么样子?
以下尝试均未成功:

EXECUTE 'INSERT INTO my_table VALUES ' || NEW;
EXECUTE 'INSERT INTO my_table VALUES ' || NEW.*;
EXECUTE 'INSERT INTO my_table SELECT * FROM ' || NEW;
Run Code Online (Sandbox Code Playgroud)

postgresql trigger plpgsql update record

9
推荐指数
2
解决办法
6630
查看次数

使用数组中的参数值动态执行 PostgresSQL

我想知道这在 Postgres 中是否可行:

最好用一个人为的例子来解释:

create or replace function test_function(filter_param1 varchar default null
                                       , filter_param2 varchar default null)
  returns integer as
$$ 
declare
  stmt text;
  args varchar[];
  wher varchar[];
  retid integer;
begin
  if filter_param1 is not null then 
    array_append(args, filter_param1);
    array_append(wher, 'parameter_name = $1');
  end if;
  if filter_param2 is not null then 
    array_append(args, filter_param2);
    array_append(wher, 'parameter_name = $2');
  end if;

  stmt := 'select id from mytable where ' || array_to_string(wher, ' or ');
  execute stmt into retid using args;

  return retid; …
Run Code Online (Sandbox Code Playgroud)

postgresql stored-procedures dynamic-sql parameter plpgsql

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

如何在 Postgresql 中转换为 int 数组?

我想从 ARGV[] 转换到 PostgreSQL 中的 int 数组,我在代码中用TODO标记了伪代码。x86_64-unknown-linux-gnu 上 PostgreSQL 9.4.3 中的代码,由 gcc (Debian 4.9.2-10) 4.9.2 编译,64 位:

CREATE TABLE measurements (
        measurement_id SERIAL PRIMARY KEY NOT NULL,
        measurement_size_in_bytes INTEGER NOT NULL
);

CREATE TABLE events (
        event_id SERIAL PRIMARY KEY NOT NULL, 
        measurement_id INTEGER NOT NULL, 
        event_index_start INTEGER NOT NULL,
        event_index_end INTEGER NOT NULL
);

CREATE OR REPLACE FUNCTION insaft_function() 
    RETURNS TRIGGER AS 
$func$
BEGIN 
  -- TODO Loop until TG_ARGV[0] empty
INSERT INTO events (measurement_id, event_index_start, event_index_end) 
SELECT …
Run Code Online (Sandbox Code Playgroud)

postgresql insert plpgsql cast array

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

以列名为参数修改行的触发函数

我正在尝试在 Postgres 9.4 中编写一个触发器函数。像这样的东西(还没有工作):

  CREATE FUNCTION set_point_from_coords(source _regclass, target _regclass) 
    RETURNS trigger AS $func$
  BEGIN
    NEW.target := ST_SetSRID(ST_Point(NEW.source[1], NEW.source[2]), 4326);
    RETURN NEW;
  END;
  $func$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

在这种情况下,target是一个类型的列geometry并且source是一个小数数组。

当一行插入coords数组时,我想将其转换为point. 如果我只是对列名进行硬编码,则上述方法会起作用,但我想使用相同的函数为不同的表和不同的列对执行此操作。而且我对它INSERT本身没有直接控制权。
这是我的一些实验:http : //sqlfiddle.com/#!15/ddddcd/1

找到了这篇相关的博客文章,我很难解析它。

如果这样更容易编码,我可以在插入/更新之后而不是之前运行它。

postgresql trigger dynamic-sql plpgsql

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

PostgreSQL 在查询 INSTEAD OF 触发器时使用 NEW

我无法让 INSTEAD OF 触发器正常工作,而且我想我误解了如何使用 NEW。考虑以下简化场景:

CREATE TABLE Product (
  product_id SERIAL PRIMARY KEY,
  product_name VARCHAR
);
CREATE TABLE Purchase (
  purchase_id SERIAL PRIMARY KEY,
  product_id INT REFERENCES Product,
  when_bought DATE
);

CREATE VIEW PurchaseView AS
SELECT purchase_id, product_name, when_bought
FROM Purchase LEFT JOIN Product USING (product_id);
Run Code Online (Sandbox Code Playgroud)

我希望能够创建INSTEAD OF触发器以允许我直接插入到 中PurchaseView,例如:

INSERT INTO Product(product_name) VALUES ('foo');
INSERT INTO PurchaseView(product_name, when_bought) VALUES ('foo', NOW());
Run Code Online (Sandbox Code Playgroud)

我的想法是这样的:

CREATE OR REPLACE FUNCTION insert_purchaseview_func()
  RETURNS trigger AS
$BODY$
BEGIN
  INSERT INTO Purchase(product_id, when_bought) …
Run Code Online (Sandbox Code Playgroud)

postgresql trigger syntax plpgsql

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

COMMIT 在 PostgreSQL 9.5 中的匿名 plgpsql 函数中工作吗?

我正在将大量大文件导入到要使用匿名 plpgsql 代码块中的循环进行分区的多个表中$do$

$do$
BEGIN
    FOR yyyy in 2012..2016 THEN 
        EXECUTE $$COPY table$$||yyyy||$$ FROM 'E:\data\file$$||yyyy||$$.csv DELIMITER ',' CSV;$$;
    END LOOP;
END;
$do$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

整个过程大约需要 15 个小时,我希望如果在某个时候出现导入错误,所有导入都不会回滚。

IIRCCOMMIT在存储函数中不起作用,因为整个函数被视为单个事务。

文档中$do$

代码块被视为没有参数的函数体,返回 void。它被解析和执行一次。

我假设这意味着整个$do$事务是一个事务,因此块内的提交将不起作用。我对么?

postgresql transaction plpgsql postgresql-9.5

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