标签: plpgsql

如何在PostgreSQL中进行大型非阻塞更新?

我想在PostgreSQL中对表进行大量更新,但我不需要在整个操作中维护事务完整性,因为我知道我正在更改的列不会被写入或读取更新.我想知道psql控制台中是否有一种简单的方法可以更快地完成这些类型的操作.

例如,假设我有一个名为"orders"的表,有3500万行,我想这样做:

UPDATE orders SET status = null;
Run Code Online (Sandbox Code Playgroud)

为避免被转移到offtopic讨论,让我们假设3500万列的所有状态值当前都设置为相同(非空)值,从而使索引无用.

此语句的问题是需要很长时间才能生效(仅因为锁定),并且所有更改的行都将被锁定,直到整个更新完成.此更新可能需要5个小时,而类似

UPDATE orders SET status = null WHERE (order_id > 0 and order_id < 1000000);
Run Code Online (Sandbox Code Playgroud)

可能需要1分钟.超过3500万行,执行上述操作并将其分成35块只需要35分钟,节省了4小时25分钟.

我可以用脚本进一步分解它(在这里使用伪代码):

for (i = 0 to 3500) {
  db_operation ("UPDATE orders SET status = null
                 WHERE (order_id >" + (i*1000)"
             + " AND order_id <" + ((i+1)*1000) " +  ")");
}
Run Code Online (Sandbox Code Playgroud)

此操作可能仅在几分钟内完成,而不是35分钟.

所以这归结为我真正的要求.我不想写一个怪异的脚本来分解操作,每次我想做这样一个大的一次性更新.有没有办法在SQL中完成我想要的东西?

postgresql dblink transactions plpgsql sql-update

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

将选择查询的输出存储在postgres中的一个数组中

我的代码是:

SELECT column_name
FROM information.SCHEMA.columns
WHERE table_name = 'aean'
Run Code Online (Sandbox Code Playgroud)

它返回表的列名aean.
现在我宣布了一个数组:

DECLARE colnames text[]
Run Code Online (Sandbox Code Playgroud)

如何在列号数组中存储select的输出.
是否需要初始化colnames?

sql arrays postgresql plpgsql

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

如何在不创建函数的情况下执行pl/pgsql代码?

使用SQL Server,我可以通过SQL Server Management Studio或任何其他客户端使用完整的过程逻辑执行代码即席T-SQL代码.我已经开始使用PostgreSQL并且遇到了一些区别,因为PGSQL需要在函数中嵌入任何逻辑.

有没有办法在不创建执行函数的情况下执行PL/PGSQL代码?

postgresql plpgsql

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

Postgres FOR LOOP

我试图从表中获取25个15,000个ID的随机样本.而不是每次都手动按下运行,我正在尝试循环.我完全理解的不是Postgres的最佳用法,但它是我的工具.这是我到目前为止:

for i in 1..25 LOOP
   insert into playtime.meta_random_sample
   select i, ID
   from   tbl
   order  by random() limit 15000
end loop
Run Code Online (Sandbox Code Playgroud)

random postgresql stored-procedures for-loop plpgsql

46
推荐指数
3
解决办法
14万
查看次数

在plpgsql中循环遍历数组维度

在plpgsql中,我想从二维数组中逐个获取数组内容.

DECLARE
  m varchar[];
  arr varchar[][] := array[['key1','val1'],['key2','val2']];
BEGIN
  for m in select arr
  LOOP
    raise NOTICE '%',m;
  END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)

但上面的代码返回:

{{key1,val1},{key2,val2}}
Run Code Online (Sandbox Code Playgroud)

在一条线上.我希望能够循环并调用另一个函数,该函数采用如下参数:

another_func(key1,val1)
Run Code Online (Sandbox Code Playgroud)

arrays postgresql for-loop plpgsql multidimensional-array

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

DROP FUNCTION不知道参数的数量/类型?

我将所有功能都保存在一个文本文件中'CREATE OR REPLACE FUNCTION somefunction'.因此,如果我添加或更改某些功能,我只需将文件提供给psql.

现在,如果我向现有函数添加或删除参数,它会创建一个具有相同名称的重载,并按照确切的顺序删除所有参数类型中的原始I类型,这是一种单调乏味的操作.

是否有某种通配符,我可以使用DROP具有给定名称的所有函数,所以我可以添加DROP FUNCTION行到我的文件的顶部?

postgresql dynamic-sql plpgsql sql-drop

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

检查约束中的SQL子查询

我可以在Check约束中创建SQL子查询吗?

我有一个post表中的列id, owner
我有另一个表action的列user_id, post_id
user的列id

post_id -> post.id并且user_id -> user.idpost.owner -> user.id

现在我想约束post(post_id).id != user_id桌子action

怎么可能?

postgresql plpgsql foreign-key-relationship check-constraints

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

PL/pgSQL检查是否存在行

我正在PL/pgSQL中编写一个函数,我正在寻找检查行是否存在的最简单方法.
现在我正在选择一个integer进入a boolean,这不起作用.我对PL/pgSQL还没有足够的经验知道最好的方法.

这是我的功能的一部分:

DECLARE person_exists boolean;
BEGIN

person_exists := FALSE;

SELECT "person_id" INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists THEN
  -- Do something
END IF;

END; $$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

更新 - 我现在正在做这样的事情:

DECLARE person_exists integer;
BEGIN

person_exists := 0;

SELECT count("person_id") INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists < 1 THEN
  -- Do something
END IF;
Run Code Online (Sandbox Code Playgroud)

sql postgresql exists plpgsql postgresql-9.1

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

遗忘的赋值运算符"="和常见的":="

PL/pgSQL的文档说,变量的声明和赋值完成:=.但是简单,更短,更现代 (见脚注) =似乎按预期工作:

    CREATE OR REPLACE FUNCTION foo() RETURNS int AS $$
    DECLARE
      i int;
    BEGIN
      i = 0;  
      WHILE NOT i = 25 LOOP
          i = i + 1;
          i = i * i;
      END LOOP;
      RETURN i;
    END;
    $$ LANGUAGE plpgsql;

    > SELECT foo();
    25
Run Code Online (Sandbox Code Playgroud)

请注意,Pl/pgSQL可以清楚地区分分配和比较,如行中所示

      WHILE NOT i = 25 LOOP
Run Code Online (Sandbox Code Playgroud)

所以,问题是:

  • 我没有在文档中找到提及和/或解释这个的部分吗?
  • 是否有使用=代替的已知后果:=

编辑/脚注:

请使用" 简短,不完整和错误的编程语言历史 "中的"更现代"部分:

1970年 - Niklaus Wirth创建了Pascal,一种程序语言.批评者立即谴责Pascal,因为它使用"x:= x + y"语法而不是更熟悉的类C"x = x + y".尽管C还没有被发明,但这种批评仍在发生. …

postgresql plpgsql assignment-operator colon-equals

41
推荐指数
2
解决办法
8254
查看次数

错误:未终止的引用字符串在或附近

在使用ANT执行下面显示的触发器代码时,我收到错误

org.postgresql.util.PSQLException: ERROR: unterminated quoted string at or near "' DECLARE timeout integer"
Position: 57
Run Code Online (Sandbox Code Playgroud)

我能够通过PGADmin(由postgres提供)和命令行实用程序"psql"成功执行以下代码并添加触发器功能但是在通过ANT执行时它每次都会失败

BEGIN TRANSACTION;

CREATE OR REPLACE FUNCTION sweeper() RETURNS trigger as '
    DECLARE
    timeout integer;
    BEGIN
    timeout = 30 * 24 * 60 * 60 ;
        DELETE FROM diagnosticdata WHERE current_timestamp - teststarttime  > (timeout * ''1 sec''::interval);
        return NEW;
    END;
' LANGUAGE 'plpgsql';

-- Trigger: sweep on diagnosticdata

CREATE TRIGGER sweep
  AFTER INSERT
  ON diagnosticdata
  FOR EACH ROW
  EXECUTE PROCEDURE sweeper();

END;
Run Code Online (Sandbox Code Playgroud)

ant postgresql triggers plpgsql

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