这是我用于创建临时表的语法:
create temp table tmpTable (id bigint not null, primary key (id)) on commit drop;
Run Code Online (Sandbox Code Playgroud)
我知道这意味着在每个事务结束时,此表将被删除.我的问题是,如果同一会话中的两个或多个线程创建并将值插入临时表,它们每个都会获得自己的实例,还是整个会话中共享的临时实例?如果它是共享的,有没有办法让它在每个线程本地?
谢谢Netta
临时表对同一会话中的所有操作都是可见的.所以,你不能创建同名的临时表在同一个会话你放弃存在的一个(提交你的情况的交易)前.
您可能想要使用:
CREATE TEMP TABLE tmptbl IF NOT EXISTS ...
Run Code Online (Sandbox Code Playgroud)
要使临时表在每个"线程"本地(在同一会话中),您需要使用唯一的表名.一种方法是使用未绑定的SEQUENCE动态SQL - 使用plpgsql或DO语句等过程语言(在没有存储函数的情况下基本相同).
运行一个:
CREATE SEQUENCE myseq;
Run Code Online (Sandbox Code Playgroud)
使用:
DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq') ||'(id int)';
END;
$$
Run Code Online (Sandbox Code Playgroud)
要知道最新的表名:
SELECT 'tmp' || currval('myseq');
Run Code Online (Sandbox Code Playgroud)
或者将它全部放入plpgsql函数并返回表或重用表名.
但是,所有其他SQL命令都必须动态执行,因为普通的SQL语句使用硬编码标识符.因此,将它全部放入plpgsql函数中可能是最好的.
另一种可能的解决方案是对同一会话中的所有线程使用相同的临时表,thread_id并向表中添加一列.如果您大量使用该功能,请务必为该列编制索引.然后使用thread_id每个线程的唯一(在同一会话中).
只有一次:
CREATE SEQUENCE myseq;
Run Code Online (Sandbox Code Playgroud)
每个线程一次:
CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id := nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread
Run Code Online (Sandbox Code Playgroud)
SQL:
INSERT INTO tmptbl(thread_id, col1) VALUES
(my_id, 2), (my_id, 3), (my_id, 4);
SELECT * FROM tmptbl WHERE thread_id = my_id;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2879 次 |
| 最近记录: |