我想在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中完成我想要的东西?
我的代码是:
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 Server,我可以通过SQL Server Management Studio或任何其他客户端使用完整的过程逻辑执行代码即席T-SQL代码.我已经开始使用PostgreSQL并且遇到了一些区别,因为PGSQL需要在函数中嵌入任何逻辑.
有没有办法在不创建执行函数的情况下执行PL/PGSQL代码?
我试图从表中获取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) 在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) 我将所有功能都保存在一个文本文件中'CREATE OR REPLACE FUNCTION somefunction'
.因此,如果我添加或更改某些功能,我只需将文件提供给psql.
现在,如果我向现有函数添加或删除参数,它会创建一个具有相同名称的重载,并按照确切的顺序删除所有参数类型中的原始I类型,这是一种单调乏味的操作.
是否有某种通配符,我可以使用DROP具有给定名称的所有函数,所以我可以添加DROP FUNCTION
行到我的文件的顶部?
我可以在Check约束中创建SQL子查询吗?
我有一个post
表中的列id, owner
我有另一个表action
的列user_id, post_id
表user
的列id
post_id -> post.id
并且user_id -> user.id
还post.owner -> user.id
现在我想约束post(post_id).id != user_id
桌子action
怎么可能?
postgresql plpgsql foreign-key-relationship check-constraints
我正在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) 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还没有被发明,但这种批评仍在发生. …
在使用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) plpgsql ×10
postgresql ×10
arrays ×2
for-loop ×2
sql ×2
ant ×1
colon-equals ×1
dblink ×1
dynamic-sql ×1
exists ×1
random ×1
sql-drop ×1
sql-update ×1
transactions ×1
triggers ×1