希望为一系列物质计算最合适的计量单位,其中物质以不同(但兼容)的单位体积给出。
单位转换表存储各种单位以及这些单位之间的关系:
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) 我正在编写一个验证触发器。触发器必须验证数组的总和是否等于另一个字段。由于我有许多此验证的实例,因此我想编写一个过程并创建多个触发器,每个触发器都有一组不同的要检查的字段。
例如,我有以下架构:
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) 我是 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) 我想知道是否有办法在 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 构造,但它似乎只能处理返回值。
我想在触发器的表中插入一个 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) 我想知道这在 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) 我想从 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) 我正在尝试在 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
找到了这篇相关的博客文章,我很难解析它。
如果这样更容易编码,我可以在插入/更新之后而不是之前运行它。
我无法让 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) 我正在将大量大文件导入到要使用匿名 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在存储函数中不起作用,因为整个函数被视为单个事务。
代码块被视为没有参数的函数体,返回 void。它被解析和执行一次。
我假设这意味着整个$do$事务是一个事务,因此块内的提交将不起作用。我对么?
plpgsql ×10
postgresql ×10
trigger ×4
dynamic-sql ×2
array ×1
cast ×1
delete ×1
insert ×1
parameter ×1
record ×1
syntax ×1
transaction ×1
update ×1