首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态创建表与索引一样

动态创建表与索引一样
EN

Database Administration用户
提问于 2022-02-18 04:10:51
回答 1查看 1.3K关注 0票数 0

我正在将我们的主db从Server迁移到PostgreSQL (在这个过程中学习它)。

我需要移动的东西之一是一堆存储过程,它们生成具有动态列名的表。我的工作没有任何问题。问题是,其中一些表后来被用来获取数据,以便在另一个存储过程中生成另一个表。这些后续程序可能需要很长时间才能生成,有时需要3-5分钟。虽然这些查询相当复杂,但我怀疑这是因为动态创建的表不包含索引,甚至不包含主键。

下面是最不复杂过程的示例代码。有人能告诉我,在这个过程中,我如何在第一列(material)中添加一个主键,然后向第六列(total_open)添加额外的索引?

代码语言:javascript
运行
AI代码解释
复制
CREATE OR REPLACE PROCEDURE sap_data.sp_ssa_po_final()
 LANGUAGE plpgsql
AS $procedure$
DECLARE
    month_next_5 varchar(3) := to_char(NOW() + interval '5 month', 'mon');
    month_next_4 varchar(3) := to_char(NOW() + interval '4 month', 'mon');
    month_next_3 varchar(3) := to_char(NOW() + interval '3 month', 'mon');
    month_next_2 varchar(3) := to_char(NOW() + interval '2 month', 'mon');
    month_next_1 varchar(3) := to_char(NOW() + interval '1 month', 'mon');
    month_now varchar(3) := to_char(NOW(), 'mon');
    month_prev_1 varchar(3) := to_char(NOW() - interval '1 month', 'mon');
    month_prev_2 varchar(3) := to_char(NOW() - interval '2 month', 'mon');
    month_prev_3 varchar(3) := to_char(NOW() - interval '3 month', 'mon');
    month_prev_4 varchar(3) := to_char(NOW() - interval '4 month', 'mon');
    month_prev_5 varchar(3) := to_char(NOW() - interval '5 month', 'mon');
    month_prev_6 varchar(3) := to_char(NOW() - interval '6 month', 'mon');
    sql_string varchar(3000) := '';

BEGIN


sql_string := 'CREATE TABLE sap_ssa_po_final AS SELECT 
mat_no AS "material", 
material_descr AS "material_description", 
('||month_now||'+'||month_prev_1||'+'||month_prev_2||'+'||month_prev_3||'+'||month_prev_4||'+'||month_prev_5||'+'||month_prev_6||') as "open_till_'||month_now||'",
'||month_next_1||' AS "sum_'||month_next_1||'_qty",
'||month_next_2||' AS "sum_'||month_next_2||'_qty",
('||month_now||'+'||month_prev_1||'+'||month_prev_2||'+'||month_prev_3||'+'||month_prev_4||'+'||month_prev_5||'+'||month_prev_6||'+'||month_next_1||'+'||month_next_2||') as "total_open",
'||month_next_3||' AS "sum_'||month_next_3||'_qty",
'||month_next_4||' AS "sum_'||month_next_4||'_qty",
'||month_next_5||' AS "sum_'||month_next_5||'_qty",
NOW() as created_date 
FROM v_ssa_po_summarised';

execute sql_string;
end;
$procedure$
;

我确实尝试过在谷歌上寻找答案,但结果却很短。:(

EN

回答 1

Database Administration用户

回答已采纳

发布于 2022-02-18 17:43:00

我是被你代码中的噪音触发的。考虑一下重写。

同时,我也回答了你的问题。

代码语言:javascript
运行
AI代码解释
复制
CREATE OR REPLACE PROCEDURE sap_data.sp_ssa_po_final()
  LANGUAGE plpgsql AS
$proc$
DECLARE
   mon text[];
   sql_string text;
BEGIN
   -- prepare array with subscripts -6 to +5, and current month at index 0
   SELECT INTO mon
         ('[-6:5]={' || string_agg(to_char(m, 'mon'), ',') || '}')::text[]
   FROM   generate_series(LOCALTIMESTAMP - interval '6 mon'
                        , LOCALTIMESTAMP + interval '5 mon'
                        , interval '1 mon') m;
                        
   sql_string :=
      'CREATE TABLE public.sap_ssa_po_final AS SELECT'
   || concat_ws(E'\n   , ' 
         , E'\n     mat_no AS material'
         , 'material_descr AS material_description'
         , '(' || concat_ws('+', mon[0], mon[-1], mon[-2], mon[-3], mon[-4], mon[-5], mon[-6]) || ') AS open_till_' || mon[0]
         , mon[1] || ' AS sum_' || mon[1] || '_qty'
         , mon[2] || ' AS sum_' || mon[2] || '_qty'
         , '(' || concat_ws('+', mon[0], mon[-1], mon[-2], mon[-3], mon[-4], mon[-5], mon[-6], mon[1], mon[2]) || ') AS total_open'
         , mon[3] || ' AS sum_' || mon[3] || '_qty'
         , mon[4] || ' AS sum_' || mon[4] || '_qty'
         , mon[5] || ' AS sum_' || mon[5] || '_qty'
         , 'now() AS created_date'
         )
   || E'\nFROM v_ssa_po_summarised;'


   -- RAISE NOTICE '%', mon;
   -- RAISE NOTICE '%', sql_string;
   EXECUTE sql_string;

   -- These can be static. Spell out the schema to be sure!
   ALTER TABLE public.sap_ssa_po_final ADD PRIMARY KEY(material);
   CREATE INDEX ON public.sap_ssa_po_final (total_open);
END
$proc$;

在创建新表之后,可以使用静态代码创建主键和索引。PL/pgSQL计划并执行一个又一个语句。(这在普通SQL函数中是不可能的,因为整个函数体都是一次解析的。但是动态SQL无论如何都需要一种过程语言。)请参见:

但是,我建议将模式名称拼写出来,以避免与search_path发生意外(甚至是恶意的尝试)。我用的是public。(您的动态CREATE TABLE语句目前还没有模式。)适应你的情况。也许临时模式pg_temp是您的一种选择?请参见:

我生成月份mon的数组,当前月份的下标为0。这样可以简化相当多的内容。关于非标准数组下标:

注意concat_ws()的战略使用。请参见:

我使用LOCALTIMESTAMP而不是now()来清楚地表明,任何一种方式都将使用本地时区--这对拐角处的情况有很大的影响。在generate_series()中,它的效率也略高一些。请参见:

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/307683

复制
相关文章
JAVA动态创建表以及动态插入数据
利用JDBC驱动链接Mysql数据其实很简单的,第一要下载一个名为 “mysql-connector-java-5.1.20-bin.jar” 驱动包。并解压到相应的目录!5.1.20是版 本号到目前为止这个是最新的版本!
ZONGLYN
2019/08/08
6.7K0
Oracle 与 MySQL 的差异分析(3):创建表和索引
MySQL 的主键和 Oracle 差不多,都是对应一个唯一索引并且索引列是非空的。
一头小山猪
2020/04/10
1.3K0
创建与删除索引
索引是加速查询的主要手段,特别对于涉及多个表的查询更是如此。本节中,将介绍索引的作用、特点,以及创建和删除索引的语法。
全栈程序员站长
2021/11/15
7460
Spring Boot:实现MyBatis动态创建表
在有些应用场景中,我们会有需要动态创建和操作表的需求。比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等。这个时候就需要我们动态的生成和操作数据库表了。而我们都知道,以往我们使用MyBatis是需要提前生成包括Model,Mapper和XML映射文件的,显然因为动态生成和操作表的需求一开始表都是不存在的,所以也就不能直接通过MyBatis连接数据库来生成我们的数据访问层代码并用来访问数据库了。还好MyBatis提供了动态SQL,我们可以通过动态SQL,传入表名等信息然组装成建表和操作语句,接下来,我们就通过一个具体的案例来了解一下。
朝雨忆轻尘
2019/06/19
6.9K0
Spring Boot:实现MyBatis动态创建表
生成 MySQL 删除索引、创建索引、分析表的 SQL 语句
用户1148526
2023/10/14
3540
索引的创建与设计原则(2)(适合创建索引情况 )
 由于开启过慢查询日志bin-log, 我们就必须为我们的function指定一个参数。 主从复制,主机会将写操作记录在bin-log日志中。从机读取bin-log日志,执行语句来同步数据。如果使 用函数来操作数据,会导致从机和主键操作时间不一致。所以,默认情况下,mysql不开启创建函数设 置。
一个风轻云淡
2022/11/15
3670
索引的创建与设计原则(2)(适合创建索引情况 )
Phoenix的索引介绍与创建
在海量数据背景下,查询数据快速返回是典型的应用场景。在phoenix数据表基础之上创建索引,能够大幅提高数据的查询效率。Phoenix支持的索引有三个类型,分别是覆盖索引、全局索引、本地索引。
大数据梦想家
2021/01/26
1.6K0
Phoenix的索引介绍与创建
MySQL/Oracle索引的创建与使用
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
互联网金融打杂
2018/09/28
1K0
MySQL/Oracle索引的创建与使用
非分区表是否可以创建分区索引?
有同事问一个问题, 一张非分区表,是否可以创建分区索引? 答案是可以,但分区索引的类型有限制。 MOS这篇文章给出了答案,以及一些例子,What Is The Global Partitioned I
bisal
2019/01/29
1.7K0
【Oracle】-【创建索引】-创建索引的操作原理与一些体会
1、将index key的data读到cache。如果之前这部分数据未读到DB Cache,那么此时可能有db file scatter read write的等待事件。
bisal
2019/01/29
5660
oracle快速创建一个和已有表一样字段的表
1、创建B表,和已有的A表一样的字段,不保存A表的数据 create table BBB as select * from AAA where 1= 0
小小鱼儿小小林
2020/06/23
1.1K0
sqlserver 视图创建索引_Oracle创建索引
1、添加索引 create index 索引对象名 on 索引对应表名(表内索引对象字段名); 例:需创建包含userid属性的userinfo表。 create index userid on system.userinfo(userid);
全栈程序员站长
2022/10/04
1.4K0
用sql创建索引_sqlserver索引的建立与使用
1.创建普通索引 SQL CREATE INDEX 语法 在表上创建一个简单的索引。允许使用重复的值:
全栈程序员站长
2022/10/02
2K0
菜鸟学SSH(十八)——Hibernate动态模型+JRebel实现动态创建表
项目用的是SSH基础框架,当中有一些信息非常相似,但又不尽同样。假设每个建一个实体的话,那样实体会太多。假设分组抽象,然后继承,又不是特别有规律。鉴于这样的情况。就打算让用户自己配置要加入的字段,然后生成相应的表。
全栈程序员站长
2022/07/08
5740
菜鸟学SSH(十八)——Hibernate动态模型+JRebel实现动态创建表
ORA-01658创建表或索引报错分析
这个报错的意思是,没有足够的连续空间为表或索引创建 INITIAL extent:
雪人
2024/07/29
2190
【MySQL】回表查询与覆盖索引
InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Secondary Index)。
看、未来
2021/12/20
1.6K0
【MySQL】回表查询与覆盖索引
C# 动态创建类,动态创建表,支持多库的数据库维护方案
SqlSugar支持了3种模式的建表(无实体建表、实体建表,实体特性建表),非常的灵活
郑子铭
2023/12/13
6990
C# 动态创建类,动态创建表,支持多库的数据库维护方案
MySQL InnoDB表和索引之聚簇索引与第二索引
每个InnoDB表都有一个称之为聚簇索引(clustered index)的特殊索引,存储记录行数据。通常,聚簇索引和主索引是近义的。
授客
2019/09/10
1.1K0
索引的创建与设计原则(1)
MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。
一个风轻云淡
2022/11/15
3680
索引的创建与设计原则(1)
C# 动态创建类,动态创建表,支持多库的数据库维护方案
SqlSugar支持了3种模式的建表(无实体建表、实体建表,实体特性建表),非常的灵活
软件架构师Michael
2023/10/22
7780

相似问题

动态临时索引创建

30

Oracle:索引与表统计

10

许多表的Postresql动态索引创建

10

创建索引与ALTER添加索引- MySQLism,还是Standard?

20

在PostgreSQL中创建索引与并发创建索引的性能

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档