oracle trunc函数_Oracle的逻辑对象,openGauss都能hold住吗?

本文详细介绍了Oracle数据库对象在openGauss中的兼容性情况,包括索引、约束、视图、序列和同义词等,并提供了具体示例。
ec09546a78818435e0ed9db8ee5fc64e.gif

作者介绍

洪烨,openGauss Contributor,多年银行业系统架构设计及DBA实战经验,《DB2数据库内部解析与性能调优》作者。

除了最常用的数据库表外,数据库的逻辑对象还包括索引、约束、视图、序列、同义词等,接下来我们将逐一评估Oracle对象在openGauss中的兼容性。

一、索引

索引是一种特殊的数据结构,能够快速定位到所要查找的数据。为了提高查询效率,在创建表之后通常需要在关键字段上创建索引。按照数据结构分类,Oracle数据库中的索引分为B*树索引及位图索引。

1、B*树索引

B*树索引是数据库中最常用的索引类型,所有的叶子节点数据构成了一个有序链表。

在Oracle数据库中大多数情况下创建的索引都属于B*树索引,按照使用场景进行细分,可以分为常规索引、复合索引、唯一索引、反向索引、基于函数的索引、全局索引。

1)常规索引:

基于表中单个列建立的索引,也是最简单的索引创建方式,无需额外关键字,索引默认按照升序排序。

postgres=# create index single_index on product(name);

CREATE INDEX

2)复合索引:

基于表中多个列创建索引。

postgres=# create index mutli_index on product(id,name);

CREATE INDEX

3)唯一索引:

创建索引时,通过指定unique关键字限制索引列中的值必须唯一,与唯一约束功能类似。

postgres=# create unique index unique_index on product(id,name);

CREATE INDEX

4)反向索引:

索引列按照降序进行排序,在Oracle中通过REVERSE关键字进行创建,但openGauss中不支持关键字REVERSE,可以通过指定DESC关键字进行替代。

postgres=# create index reverse_index on product(name) REVERSE;

ERROR: syntax error at or near "REVERSE"

LINE 1: create index reverse_index on product(name) REVERSE;

postgres=# create index reverse_index on product(name desc);

CREATE INDEX

5)基于函数的索引:

基于函数的索引适用于某个字段做查询的时候经常带函数操作,openGauss中可以支持基于函数的索引。

postgres=# CREATE INDEX func_index ON product(trunc(name));

CREATE INDEX

6)分区索引:

分区表的数据量通常较大,随着数据增大,会导致分区表上的B*树的索引的性能下降,维护成本也随之升高。对于分区表而言,基于每个分区进行索引创建则十分必要。创建分区索引需要加local关键字,openGauss可以支持分区索引的场景。

postgres=# CREATE TABLE t_range_partition

( prod_id NUMBER(6)

, cust_id NUMBER

, time_id DATE

, channel_id CHAR(1)

, promo_id NUMBER(6)

, quantity_sold NUMBER(3)

, amount_sold NUMBER(10,2)

) PARTITION BY RANGE (time_id)

(PARTITION sales_q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy')) TABLESPACE pg_default, PARTITION sales_q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy')) TABLESPACE pg_default );

CREATE TABLE

postgres=# create index IDX_PARTI_RANGE_ID on t_range_partition(prod_id) local;

CREATE INDEX

2、位图索引

位图索引的存储结构与B*树差异较大,ROWID并不直接存储。位图的每个位置映射到一个可能的ROWID上,位图上每个位置的内容用于表示该行特定的值是否在位图列中。所以,位图的每个位置存储特殊行和相关ROWID的信息。如果该ROWID的行的值匹配,则该特殊rowid位置存储为"1",否则储存为"0"。

位图索引适用于该列只有几个枚举值的情况,比如性别字段,标示字段比如只有0和1的情况。openGauss当前版本暂不支持位图索引。

postgres=# create bitmap index bit_index on product(name);

ERROR: syntax error at or near "bitmap"

LINE 1: create bitmap index bit_index on product(name);

二、约束

数据库约束用来防止无效的数据进入到表中,以保护数据的实体完整性,最常见的数据库约束就是主键,大多数SQL规范中都会包含建表需要定义主键。在Oracle数据库中,数据库约束分为5类:非空约束、主键约束、唯一约束、外键约束、检查约束,openGauss可以兼容所有约束类型。

1、非空约束(NOT )

如果在列上定义了非空约束,那么当插入数据时,必须保证数据不能为,如果数据为空则无法插入,openGauss支持非空约束。

postgres=# create table t_not(

id number not ,

name varchar2(20));

CREATE TABLE

2、主键约束

当定义主键约束后,该列的值不能重复而且不能为。一张表最多只能有一个主键,但是可以由多个唯一约束。创建主键后,openGuass会自动创建表名+pkey的索引。

postgres=# create table t_primary_key(

id number not primary key,

name varchar2(20));

NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_primary_key_pkey" for table "t_primary_key"

CREATE TABLE

3、唯一约束

唯一约束与主键的区别是,当定义了唯一约束后,该列值是不能重复的,但是可以为,并且对于同一张表,唯一约束可以存在多个。创建唯一约束后,openGuass也会自动创建唯一索引。

postgres=# create table t_unique

(

product_id number not ,

product_name number not ,

product_type varchar2(50),

supplier_id number,

CONSTRAINT t_unique_u1 UNIQUE (product_id, product_name)

);

NOTICE: CREATE TABLE / UNIQUE will create implicit index "t_unique_u1" for table "t_unique"

CREATE TABLE

4、外键约束

用于定义主表和从表之间的关系,外键约束要定义在从表上,主要则必须具有主键约束或是唯一约束,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为。

外键约束会增加表插入、更新等SQL性能的额外开销,不少系统里面通过业务逻辑控制来取消外键约束。例如在数据仓库中,就推荐禁用外键约束。

postgres=# create table t1(id number);

CREATE TABLE

postgres=# create table t2(id number,cc number,constraint fk_t2_id foreign key(id) references t1(id));

ERROR: there is no unique constraint matching given keys for referenced table "t1"

5、检查约束

用于强制行数据必须满足的条件,假定在sal列上定义了check约束,并要求sal列值在5000~50000之间,如果插入数据不在此范围之间就会提示出错。

postgres=# create table t3(id number,sal number,constraint ck_t3_sal check(sal between 5000 and 50000));

CREATE TABLE

postgres=# insert into t3 values (1,6000);

INSERT 0 1

postgres=# insert into t3 values (1,600);

ERROR: new row for relation "t3" violates check constraint "ck_t3_sal"

DETAIL: Failing row contains (1, 600).

三、视图

视图主要是为了提升开发效率,作为一个定义查询语句结果的对象存在的;根据是否真实存储数据,分为关系视图及物化视图。

1、关系视图

Oracle的关系视图本身不包含任何数据,也是大家最常用的视图,通过create view... as ...简化的语法就可以创建,还可以需求将视图设置为只读形式等。注意:在当前用户下创建视图需要CREATE VIEW系统权限。openGauss可以兼容Oracle创建视图语法,但对于Oracle视图创建中的with check option以及with read only选项暂不支持。

postgres=# CREATE OR REPLACE VIEW prod_view AS select p.id, p.name from product p;

CREATE VIEW

postgres=# CREATE OR REPLACE VIEW read_view AS select p.id, p.name from product p WITH READ ONLY;

ERROR: syntax error at or near "READ"

LINE 1: ..._view AS select p.id, p.name from product p WITH READ ONLY;

postgres=# CREATE OR REPLACE VIEW check_view AS select p.id, p.name from product p WITH CHECK OPTION;

ERROR: WITH CHECK OPTION is not implemented

2、物化视图

物化视图有别于关系视图,可以像数据库表一样可以真实存储数据。openGauss可以支持物化视图的创建,但对于数据刷新需要手动刷新,不支持自动刷新。

postgres=# create materialized view mater_view as select p.id, p.name from product p;

SELECT 0

四、序列

序列可供多个用户用来产生唯一数值的数据库对象。在MySQL中可以通过自增长字段auto_increment,而Oracle中没有自增长字段功能,通常通过建立序列来实现自增长的功能,openGauss中可以支持sequence功能。

postgres=# create sequence autoincre

minvalue 1

maxvalue 9999999999999

start with 1

increment by 1;

CREATE SEQUENCE

五、同义词

同义词就是别名,可以为表、字段名建立别名,主要是为了简化书写,在当前用户下创建同义词需要 create synonym 权限。

postgres=# create synonym product_syn for product;

CREATE SYNONYM

六、总结

对象类型

分类

是否兼容

备注

索引

B*索引

兼容

REVERSE关键字需用DESC替代

位图索引

不兼容

约束

非空约束

兼容

主键约束

兼容

唯一约束

兼容

外键约束

兼容

检查约束

兼容

视图

关系视图

兼容

部分选项不兼容

物化视图

兼容

部分选项不兼容

序列

兼容

同义词

兼容

请整理出以下程序包中,关于“结算方式”的取值逻辑create or replace PACKAGE BODY cux_ap_schedule_pkg2 IS PROCEDURE main_bak(p1 OUT VARCHAR2, p2 OUT VARCHAR2, p_org_id IN NUMBER, p_vendor_f IN VARCHAR2, p_vendor_t IN VARCHAR2, p_gl_date_f IN VARCHAR2, p_gl_date_t IN VARCHAR2, p_due_date_f IN VARCHAR2, p_due_date_t IN VARCHAR2, p_yn in varchar2) IS -- v_gl_date_f DATE := trunc(fnd_date.canonical_to_date(p_gl_date_f)); v_gl_date_t DATE := trunc(fnd_date.canonical_to_date(p_gl_date_t)); v_due_date_f DATE := trunc(fnd_date.canonical_to_date(p_due_date_f)); v_due_date_t DATE := trunc(fnd_date.canonical_to_date(p_due_date_t)); v_org_name VARCHAR2(300); -- CURSOR cur_schedule IS SELECT pv.vendor_name --供应商名称 , pvsa.vendor_site_code --供应商地址 , aia.invoice_id, aia.invoice_num --发票编号 , b.displayed_field, ats.name term_name --付款方法 , to_char(aia.gl_date, 'YYYY-MM-DD') gl_date --总帐日期 , to_char(aia.invoice_date, 'YYYY-MM-DD') invoice_date --发票日期 , to_char(aia.terms_date, 'YYYY-MM-DD') terms_date --条件日期 , to_char(apsa.due_date, 'YYYY-MM-DD') due_date --到期日 , aia.invoice_currency_code --币种 , aia.invoice_amount --原币 , nvl(aia.invoice_amount, 0) * nvl(aia.exchange_rate, 1) invoice_amount_b --本位币 , apsa.amount_remaining --到期余额原币 , nvl(apsa.amount_remaining, 0) * nvl(aia.exchange_rate, 1) amount_remaining_b --到期余额本币 , aia.description --摘要 , cuxs_std_report_utl_pkg.get_ccid_segment(gcc.code_combination_id) acc_code, cuxs_std_report_utl_pkg.get_ccid_description(gcc.chart_of_accounts_id, gcc.code_combination_id) acc_desc, decode(NVL(apsa.hold_flag, 'N'), 'N', '否', '是') HOLD_FLAG, ppx.EMPLOYEE_NUMBER FROM ap_payment_schedules_all apsa, po_vendors pv, po_vendor_sites_all pvsa, ap_terms ats, ap_invoices_all aia, ap_lookup_codes b, gl_code_combinations gcc, per_people_x ppx WHERE apsa.invoice_id = aia.invoice_id AND aia.terms_id = ats.term_id AND aia.vendor_id = pv.vendor_id(+) AND aia.vendor_site_id = pvsa.vendor_site_id(+) and pv.EMPLOYEE_ID = ppx.PERSON_ID(+) AND apsa.amount_remaining <> 0 -- AND aia.org_id = p_org_id /*AND pv.segment1 >= nvl(pv.segment1, p_vendor_f) AND pv.segment1 <= nvl(pv.segment1, p_vendor_t)*/ AND aia.invoice_type_lookup_code = b.lookup_code AND b.lookup_type(+) = 'INVOICE TYPE' AND AP_INVOICES_PKG.GET_APPROVAL_STATUS(aia.INVOICE_ID, aia.INVOICE_AMOUNT, aia.PAYMENT_STATUS_FLAG, aia.INVOICE_TYPE_LOOKUP_CODE) NOT IN ('NEEDS REAPPROVAL', 'NEVER APPROVED', 'CANCELLED', 'FULL', 'UNAPPROVED') AND aia.accts_pay_code_combination_id = gcc.code_combination_id(+) AND (pv.segment1 >= p_vendor_f OR p_vendor_f IS NULL) AND (pv.segment1 <= p_vendor_t OR p_vendor_t IS NULL) AND trunc(aia.gl_date) >= trunc(nvl(v_gl_date_f, aia.gl_date)) AND trunc(aia.gl_date) <= trunc(nvl(v_gl_date_t, aia.gl_date)) AND trunc(apsa.due_date) >= trunc(nvl(v_due_date_f, apsa.due_date)) AND trunc(apsa.due_date) <= trunc(nvl(v_due_date_t, apsa.due_date)) ORDER BY pv.vendor_name, to_char(aia.invoice_date, 'YYYY-MM-DD'), aia.invoice_num; cursor cur_pro(p_invoice_id number) is select nvl(ppa1.project_id, ppa.PROJECT_ID) project_id, nvl(ppa1.SEGMENT1, ppa.SEGMENT1) pro_num, nvl(ppa1.NAME, ppa.NAME) pro_name, pav.agent_name, (select d.kb from per_people_x ppx, CUX.CUX_HR_EMPLOYEE_T emp, cux_hr_dept d where ppx.EMPLOYEE_NUMBER = emp.emp_no and emp.ou_code = d.ou_code and ppx.PERSON_ID = pav.agent_id and rownum = 1) kb, case when sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) = 0 then 0 else sum(d.AMOUNT) / sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) end pro_rate from ap_invoices_all h, ap_invoice_distributions_all d, po_distributions_all pd, po_headers_all ph, po_agents_v pav, pa_projects_all ppa, pa_projects_all ppa1 where h.INVOICE_ID = d.INVOICE_ID and d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_HEADER_ID = ph.PO_HEADER_ID(+) and ph.AGENT_ID = pav.agent_id(+) and nvl(d.PROJECT_ID, h.PROJECT_ID) = ppa1.PROJECT_ID(+) and pd.PROJECT_ID = ppa.PROJECT_ID(+) and h.INVOICE_ID = p_invoice_id and d.LINE_TYPE_LOOKUP_CODE <> 'PREPAY' group by h.INVOICE_ID, nvl(ppa1.project_id, ppa.PROJECT_ID), nvl(ppa1.SEGMENT1, ppa.SEGMENT1), nvl(ppa1.NAME, ppa.NAME), pav.agent_name, pav.agent_id; p_ret_flag VARCHAR2(2); v_sep VARCHAR2(15); --字符串之间的分隔符号,默认为逗号“,” v_line_str VARCHAR2(4000); --输出的字符串,不同的字段之间,使用V_SEP变量示的分隔符号进行分隔 p_title VARCHAR2(100); lv_pro_attr1 varchar2(200); lv_pro_attr2 varchar2(200); lv_pro_attr3 varchar2(200); lv_pro_attr4 varchar2(200); lv_pro_attr5 varchar2(200); lv_pro_class varchar2(200); lv_pro_class2 varchar2(200); BEGIN -- BEGIN SELECT hou.name INTO v_org_name FROM hr_operating_units hou WHERE hou.organization_id = p_org_id; EXCEPTION WHEN OTHERS THEN v_org_name := NULL; END; -- p_ret_flag := 'Y'; p_title := '付款计划'; -- --示以文件形式进行输出,在开发HTML报时,固定即可,不需修改 -- cux_html_reports_utl.v_report_output_mode := 'F'; v_sep := cux_html_reports_utl.g_delimiter; --输出报标题 cux_html_reports_utl.html_title(p_program_title => p_title, p_report_title => p_title); --标题输出 cux_html_reports_utl.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --输出参数 -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '实体:', p_para_value => v_org_name); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商从:', p_para_value => p_vendor_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商至:', p_para_value => p_vendor_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期从:', p_para_value => p_gl_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期至:', p_para_value => p_gl_date_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日从:', p_para_value => p_due_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日至:', p_para_value => p_due_date_t); END IF; --开始进行内容的输出,下行的width=1200,用于进行输出格的宽度设置 --cux_html_report_pkg.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --将格标题,用逗号分隔后,连接成一个字符串,注意:最后一个字段之后,也要有个逗号。 if p_yn = 'N' then v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,发票金额原币,发票金额本币,到期余额原币,到期余额本币,摘要,是否暂挂,负债账户,负债说明,'; --输出格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || rec_schedule.invoice_amount || v_sep || rec_schedule.invoice_amount_b || v_sep || rec_schedule.amount_remaining || v_sep || rec_schedule.amount_remaining_b || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); END LOOP; else v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,项目编码,项目名称,项目大分类,项目分类,项目代码,项目发票金额原币,项目发票金额本币,项目到期余额原币,项目到期余额本币,摘要,是否暂挂,负债账户,负债说明,采购员,组别,'; --输出格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP for l in cur_pro(rec_schedule.invoice_id) loop SCUX_CST_INVEST_REPORT_PKG.get_project_info2(l.project_id, null, lv_pro_attr1, lv_pro_attr2, lv_pro_attr3, lv_pro_attr4, lv_pro_attr5, lv_pro_class, lv_pro_class2); cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || l.pro_num || v_sep || l.pro_name || v_sep || lv_pro_class2 || v_sep || lv_pro_class || v_sep || lv_pro_attr3 || v_sep || rec_schedule.invoice_amount * l.pro_rate || v_sep || rec_schedule.invoice_amount_b * l.pro_rate || v_sep || rec_schedule.amount_remaining * l.pro_rate || v_sep || rec_schedule.amount_remaining_b * l.pro_rate || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep || l.agent_name || v_sep || l.kb || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); end loop; end loop; end if; END; PROCEDURE main(p1 OUT VARCHAR2, p2 OUT VARCHAR2, p_org_id IN NUMBER, p_vendor_f IN VARCHAR2, p_vendor_t IN VARCHAR2, p_gl_date_f IN VARCHAR2, p_gl_date_t IN VARCHAR2, p_due_date_f IN VARCHAR2, p_due_date_t IN VARCHAR2, p_yn in varchar2 ,P_save In Varchar2 Default 'N' ) IS -- v_gl_date_f DATE := trunc(fnd_date.canonical_to_date(p_gl_date_f)); v_gl_date_t DATE := trunc(fnd_date.canonical_to_date(p_gl_date_t)); v_due_date_f DATE := trunc(fnd_date.canonical_to_date(p_due_date_f)); v_due_date_t DATE := trunc(fnd_date.canonical_to_date(p_due_date_t)); v_org_name VARCHAR2(300); lr_ex_info cux_ap_schd_extra_t %rowtype; ln_request_id number := fnd_global.CONC_REQUEST_ID; ld_crr_date date := sysdate; l_extra9 VARCHAR2(50) :='达标'; l_extra10 VARCHAR2(50) :='正常'; -- CURSOR cur_schedule IS SELECT pv.vendor_name --供应商名称 , pv.VENDOR_ID, aia.GL_DATE gl_date_d, aia.INVOICE_DATE invoice_date_d, aia.TERMS_DATE terms_date_d, apsa.DUE_DATE due_date_d, pvsa.vendor_site_code --供应商地址 , aia.invoice_id, aia.invoice_num --发票编号 , b.displayed_field, ats.name term_name --付款方法 , to_char(aia.gl_date, 'YYYY-MM-DD') gl_date --总帐日期 , to_char(aia.invoice_date, 'YYYY-MM-DD') invoice_date --发票日期 , to_char(aia.terms_date, 'YYYY-MM-DD') terms_date --条件日期 , to_char(apsa.due_date, 'YYYY-MM-DD') due_date --到期日 , aia.invoice_currency_code --币种 , aia.invoice_amount --原币 , nvl(aia.invoice_amount, 0) * nvl(aia.exchange_rate, 1) invoice_amount_b --本位币 , apsa.amount_remaining --到期余额原币 , nvl(apsa.amount_remaining, 0) * nvl(aia.exchange_rate, 1) amount_remaining_b --到期余额本币 , aia.description --摘要 , cuxs_std_report_utl_pkg.get_ccid_segment(gcc.code_combination_id) acc_code, cuxs_std_report_utl_pkg.get_ccid_description(gcc.chart_of_accounts_id, gcc.code_combination_id) acc_desc, decode(NVL(apsa.hold_flag, 'N'), 'N', '否', '是') HOLD_FLAG, ppx.EMPLOYEE_NUMBER FROM ap_payment_schedules_all apsa, po_vendors pv, po_vendor_sites_all pvsa, ap_terms ats, ap_invoices_all aia, ap_lookup_codes b, gl_code_combinations gcc, per_people_x ppx WHERE apsa.invoice_id = aia.invoice_id AND aia.terms_id = ats.term_id AND aia.vendor_id = pv.vendor_id(+) AND aia.vendor_site_id = pvsa.vendor_site_id(+) and pv.EMPLOYEE_ID = ppx.PERSON_ID(+) AND apsa.amount_remaining <> 0 -- and NVL(apsa.hold_flag, 'N')='N' -- AND aia.org_id = p_org_id /*AND pv.segment1 >= nvl(pv.segment1, p_vendor_f) AND pv.segment1 <= nvl(pv.segment1, p_vendor_t)*/ AND aia.invoice_type_lookup_code = b.lookup_code AND b.lookup_type(+) = 'INVOICE TYPE' AND AP_INVOICES_PKG.GET_APPROVAL_STATUS(aia.INVOICE_ID, aia.INVOICE_AMOUNT, aia.PAYMENT_STATUS_FLAG, aia.INVOICE_TYPE_LOOKUP_CODE) NOT IN ('NEEDS REAPPROVAL', 'NEVER APPROVED', 'CANCELLED', 'FULL', 'UNAPPROVED') AND aia.accts_pay_code_combination_id = gcc.code_combination_id(+) AND (pv.segment1 >= p_vendor_f OR p_vendor_f IS NULL) AND (pv.segment1 <= p_vendor_t OR p_vendor_t IS NULL) AND trunc(aia.gl_date) >= trunc(nvl(v_gl_date_f, aia.gl_date)) AND trunc(aia.gl_date) <= trunc(nvl(v_gl_date_t, aia.gl_date)) AND trunc(apsa.due_date) >= trunc(nvl(v_due_date_f, apsa.due_date)) AND trunc(apsa.due_date) <= trunc(nvl(v_due_date_t, apsa.due_date)) ORDER BY pv.vendor_name, to_char(aia.invoice_date, 'YYYY-MM-DD'), aia.invoice_num; cursor cur_pro(p_invoice_id number) is select nvl(ppa1.project_id, ppa.PROJECT_ID) project_id, nvl(ppa1.SEGMENT1, ppa.SEGMENT1) pro_num, nvl(ppa1.NAME, ppa.NAME) pro_name, nvl(pt1.ATTRIBUTE1,pt.ATTRIBUTE1) CU, pav.agent_name, (select d.kb from per_people_x ppx, CUX.CUX_HR_EMPLOYEE_T emp, cux_hr_dept d where ppx.EMPLOYEE_NUMBER = emp.emp_no and emp.ou_code = d.ou_code and ppx.PERSON_ID = pav.agent_id and rownum = 1) kb, case when sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) = 0 then 0 else sum(d.AMOUNT) / sum(sum(d.AMOUNT)) over(partition by h.INVOICE_ID) end pro_rate from ap_invoices_all h, ap_invoice_distributions_all d, po_distributions_all pd, po_headers_all ph, po_agents_v pav, pa_projects_all ppa, pa_projects_all ppa1, pa_tasks pt, pa_tasks pt1 where h.INVOICE_ID = d.INVOICE_ID and d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_HEADER_ID = ph.PO_HEADER_ID(+) and ph.AGENT_ID = pav.agent_id(+) and nvl(d.PROJECT_ID, h.PROJECT_ID) = ppa1.PROJECT_ID(+) and pd.PROJECT_ID = ppa.PROJECT_ID(+) and ppa.PROJECT_ID= pt.PROJECT_ID(+) and ppa1.PROJECT_ID = pt1.PROJECT_ID(+) and h.INVOICE_ID = p_invoice_id and d.LINE_TYPE_LOOKUP_CODE <> 'PREPAY' group by h.INVOICE_ID, nvl(ppa1.project_id, ppa.PROJECT_ID), nvl(ppa1.SEGMENT1, ppa.SEGMENT1), nvl(ppa1.NAME, ppa.NAME), nvl(pt1.ATTRIBUTE1,pt.ATTRIBUTE1), pav.agent_name, pav.agent_id; p_ret_flag VARCHAR2(2); v_sep VARCHAR2(15); --字符串之间的分隔符号,默认为逗号“,” v_line_str VARCHAR2(4000); --输出的字符串,不同的字段之间,使用V_SEP变量示的分隔符号进行分隔 p_title VARCHAR2(100); lv_pro_attr1 varchar2(200); lv_pro_attr2 varchar2(200); lv_pro_attr3 varchar2(200); lv_pro_attr4 varchar2(200); lv_pro_attr5 varchar2(200); lv_pro_class varchar2(200); lv_pro_class2 varchar2(200); ln_bill_months number; ln_pay_months number; BEGIN -- BEGIN SELECT hou.name INTO v_org_name FROM hr_operating_units hou WHERE hou.organization_id = p_org_id; EXCEPTION WHEN OTHERS THEN v_org_name := NULL; END; -- p_ret_flag := 'Y'; p_title := '付款计划'; -- --示以文件形式进行输出,在开发HTML报时,固定即可,不需修改 -- cux_html_reports_utl.v_report_output_mode := 'F'; v_sep := cux_html_reports_utl.g_delimiter; --输出报标题 cux_html_reports_utl.html_title(p_program_title => p_title, p_report_title => p_title); --标题输出 cux_html_reports_utl.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --输出参数 -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '实体:', p_para_value => v_org_name); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商从:', p_para_value => p_vendor_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '供应商至:', p_para_value => p_vendor_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期从:', p_para_value => p_gl_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '总帐日期至:', p_para_value => p_gl_date_t); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日从:', p_para_value => p_due_date_f); END IF; -- IF p_org_id IS NOT NULL THEN cux_html_reports_utl.output_para(p_para_name => '到期日至:', p_para_value => p_due_date_t); END IF; --开始进行内容的输出,下行的width=1200,用于进行输出格的宽度设置 --cux_html_report_pkg.output_line('<table width=100% style="border-collapse:collapse; border:none; font-family: 宋体; font-size: 10pt" border=1 bordercolor=#000000 cellspacing="0">'); --将格标题,用逗号分隔后,连接成一个字符串,注意:最后一个字段之后,也要有个逗号。 if p_yn = 'N' then v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,发票金额原币,发票金额本币,到期余额原币,到期余额本币,摘要,是否暂挂,负债账户,负债说明,'; --输出格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); -- FOR rec_schedule IN cur_schedule LOOP cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || rec_schedule.invoice_amount || v_sep || rec_schedule.invoice_amount_b || v_sep || rec_schedule.amount_remaining || v_sep || rec_schedule.amount_remaining_b || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); END LOOP; else v_line_str := /*'序号,*/ '供应商名称,员工工号,地点,发票编号,发票类型,条件日期,付款条件,总帐日期,发票日期,到期日,币种,BU,CU,项目编码,项目名称,项目大分类,项目分类,项目代码,项目发票金额原币,项目发票金额本币,项目到期余额原币,项目到期余额本币,摘要,是否暂挂, 负债账户,负债说明,采购员,组别,物料类型,采购地点,结算账期,付款方式,结算方式,支付账期,付款说明,限额,是否达标,备注,'; --输出格标题 cux_html_reports_utl.line_title(p_title_string => v_line_str); if P_save='Y' then delete from cux_ap_schd_extra_t; end if; FOR rec_schedule IN cur_schedule LOOP for l in cur_pro(rec_schedule.invoice_id) loop lr_ex_info := null; lr_ex_info.gl_date := rec_schedule.gl_date_d; lr_ex_info.vendor_name := rec_schedule.vendor_name; lr_ex_info.emp_num := rec_schedule.employee_number; lr_ex_info.site_name := rec_schedule.vendor_site_code; lr_ex_info.invoice_num := rec_schedule.invoice_num; lr_ex_info.invoice_type := rec_schedule.displayed_field; lr_ex_info.term_date := rec_schedule.terms_date_d; lr_ex_info.term_name := rec_schedule.term_name; lr_ex_info.gl_date := rec_schedule.gl_date_d; lr_ex_info.invoice_date := rec_schedule.invoice_date_d; lr_ex_info.due_date := rec_schedule.due_date_d; lr_ex_info.currency_code := rec_schedule.invoice_currency_code; lr_ex_info.proj_code := l.pro_num; lr_ex_info.proj_name := l.pro_name; lr_ex_info.proj_amount := rec_schedule.invoice_amount * l.pro_rate; lr_ex_info.proj_amount_b := rec_schedule.invoice_amount_b * l.pro_rate; lr_ex_info.proj_due_amount := rec_schedule.amount_remaining * l.pro_rate; lr_ex_info.proj_due_amount_b := rec_schedule.amount_remaining_b * l.pro_rate; lr_ex_info.description := rec_schedule.description; lr_ex_info.hold_flag := rec_schedule.hold_flag; lr_ex_info.cr_code := rec_schedule.acc_code; lr_ex_info.cr_desc := rec_schedule.acc_desc; lr_ex_info.agent_name := l.agent_name; lr_ex_info.dept := l.kb; lr_ex_info.request_id := ln_request_id; lr_ex_info.creation_date := ld_crr_date; begin select aa.SEGMENT1, cc.site,cc.big_cate into lr_ex_info.extra10, lr_ex_info.extra1,lr_ex_info.extra8 from (select item.SEGMENT1, row_number() over(order by d.AMOUNT desc) rnum from ap_invoice_distributions_all d, po_distributions_all pd, po_lines_all pl, mtl_system_items_b item where d.PO_DISTRIBUTION_ID = pd.PO_DISTRIBUTION_ID(+) and pd.PO_LINE_ID = pl.PO_LINE_ID(+) and pl.ITEM_ID = item.INVENTORY_ITEM_ID(+) and item.ORGANIZATION_ID(+) = po_lines_sv4.get_inventory_orgid(pl.ORG_ID) and d.INVOICE_ID = rec_schedule.invoice_id and nvl(pd.PROJECT_ID, 0) = nvl(l.project_id, 0)) aa, CUX_AP_ITEM_CATE cc where aa.rnum = 1 and cc.big_code = substr(aa.SEGMENT1, 1, 2); exception when others then lr_ex_info.extra1 := '服务采购'; end; select (extract(year from sysdate) - extract(year from lr_ex_info.gl_date)) * 12 + (extract(month from sysdate) - extract(month from lr_ex_info.gl_date)) into ln_bill_months from dual; if ln_bill_months <= 0 then lr_ex_info.extra2 := '当月结算'; else lr_ex_info.extra2 := '月结' || 30 * ln_bill_months || '天'; end if; begin select c.payment_name, c.payment_name || '-' || c.payment_days, c.term_total, c.line_credit, c.payment_days into lr_ex_info.extra3, lr_ex_info.extra4, lr_ex_info.extra6, lr_ex_info.extra7, ln_pay_months from ap_suppliers t, CUX_AP_LINE_CREDIT c where t.SEGMENT1 = c.segment1 and t.VENDOR_ID = rec_schedule.vendor_id and c.ORG_ID = p_org_id; exception when others then lr_ex_info.extra3 := '现结'; lr_ex_info.extra4 := '现结'; lr_ex_info.extra6 := '现结'; ln_pay_months := 0; end; if ln_bill_months + ln_pay_months <= 0 then lr_ex_info.extra5 := '当月结算'; else lr_ex_info.extra5 := '月结' || (30 * ln_bill_months + ln_pay_months)|| '天'; end if; SCUX_CST_INVEST_REPORT_PKG.get_project_info2(l.project_id, null, lv_pro_attr1, lv_pro_attr2, lv_pro_attr3, lv_pro_attr4, lv_pro_attr5, lv_pro_class, lv_pro_class2); lr_ex_info.proj_big_cate := lv_pro_class2; lr_ex_info.proj_cate := lv_pro_class; lr_ex_info.proj_attr3 := lv_pro_attr3; lr_ex_info.prod_line := lv_pro_attr2; lr_ex_info.cu := l.CU; if P_save='Y' then --delete from cux_ap_schd_extra_t; insert into cux_ap_schd_extra_t values lr_ex_info; end if; cux_html_reports_utl.line_title(p_title_string => rec_schedule.vendor_name || v_sep || rec_schedule.employee_number || '*** nowrap x:str ' || v_sep || rec_schedule.vendor_site_code || v_sep || rec_schedule.invoice_num || '*** nowrap x:str ' || v_sep || rec_schedule.displayed_field || v_sep || rec_schedule.terms_date || v_sep || rec_schedule.term_name || v_sep || rec_schedule.gl_date || v_sep || rec_schedule.invoice_date || v_sep || rec_schedule.due_date || v_sep || rec_schedule.invoice_currency_code || v_sep || lv_pro_attr2 || v_sep || l.CU || v_sep || l.pro_num || v_sep || l.pro_name || v_sep || lv_pro_class2 || v_sep || lv_pro_class || v_sep || lv_pro_attr3 || v_sep || rec_schedule.invoice_amount * l.pro_rate || v_sep || rec_schedule.invoice_amount_b * l.pro_rate || v_sep || rec_schedule.amount_remaining * l.pro_rate || v_sep || rec_schedule.amount_remaining_b * l.pro_rate || v_sep || rec_schedule.description || v_sep || rec_schedule.hold_flag || v_sep || rec_schedule.acc_code || v_sep || rec_schedule.acc_desc || v_sep || l.agent_name || v_sep || l.kb || v_sep || lr_ex_info.extra8 || v_sep || lr_ex_info.extra1 || v_sep || lr_ex_info.extra2 || v_sep || lr_ex_info.extra3 || v_sep || lr_ex_info.extra4 || v_sep || lr_ex_info.extra5 || v_sep || lr_ex_info.extra6 || v_sep || lr_ex_info.extra7 || v_sep || l_extra9 || v_sep || l_extra10 || v_sep, p_with_other_attr => 'Y', p_attr_delimiter => '***', p_delimiter => v_sep); end loop; end loop; end if; END; END cux_ap_schedule_pkg2;
最新发布
08-16
SELECT T10.CALENDAR_DATE, SUM (CASE WHEN T10.LOT_CATEGORY IN ('ENG','PROD') THEN T10.COMPONENT_QTY ELSE 0 END )EOH, SUM (CASE WHEN T10.LOT_CATEGORY ='ENG' THEN T10.COMPONENT_QTY ELSE 0 END ) ENG, SUM (CASE WHEN T10.LOT_STATE IN ('hold','running hold') THEN T10.COMPONENT_QTY ELSE 0 END ) HOLD_QTY, SUM (CASE WHEN T10.LOT_STATE IN ('bank') THEN T10.COMPONENT_QTY ELSE 0 END ) BANK_QTY FROM (SELECT DM.CALENDAR_DATE , L1.LOT_CATEGORY,L1.LOT_STATE,L1.COMPONENT_QTY FROM (SELECT DISTINCT L1.LOT_NAME,TO_DATE(L1.RUN_TIME_DATE,'YYYY-MM-DD') CALENDAR_DATE,L1.RUN_TIME_HOUR,L1.RUN_TIMESTAMP,L1.COMPONENT_QTY,L1.LOT_STATE,L1.LOT_CATEGORY FROM RPTDW.LOT_MASTER_SNAPSHOT_HOUR L1 WHERE L1.RUN_TIME_DATE <= TO_CHAR(TRUNC(SYSDATE),'YYYY-MM-DD') AND L1.RUN_TIME_HOUR ='07:30' AND L1.lot_CATEGORY <> 'NPW' AND L1.LOT_NAME IN (SELECT DISTINCT L1.LOT_NAME FROM RPTDW.LOT_STEP_HISTORY L1 WHERE L1.LOT_PURPOSE LIKE 'CS%' AND L1.PRODUCT_NAME IN (SELECT PRODUCT_NAME FROM INPUT_PRODUCT_CATEGORY_MAPPING_INFO WHERE PRODUCT_CATEGORY = 'MassProduction' ))) L1, RPTDW.DAY_MASTER DM WHERE DM.CALENDAR_DATE = L1.CALENDAR_DATE-1 AND TRUNC(DM.CALENDAR_DATE, 'MM') = TO_DATE('${MONTHID}'))T10 GROUP BY T10.CALENDAR_DATE UNION ALL SELECT * FROM (SELECT TO_DATE (L1.RUN_TIME_DATE ,'YYYY-MM-DD') CALENDAR_DATE , SUM (CASE WHEN L1.LOT_CATEGORY IN ('ENG','PROD') THEN L1.COMPONENT_QTY ELSE 0 END )EOH, SUM (CASE WHEN L1.LOT_CATEGORY ='ENG' THEN L1.COMPONENT_QTY ELSE 0 END ) ENG, SUM (CASE WHEN L1.LOT_STATE IN ('HOLD','RUNNING HOLD') THEN L1.COMPONENT_QTY ELSE 0 END ) HOLD_QTY, SUM (CASE WHEN L1.LOT_STATE IN ('BANK') THEN L1.COMPONENT_QTY ELSE 0 END ) BANK_QTY FROM (SELECT DISTINCT L1.RUN_TIME_DATE , L1.RUN_TIME_HOUR ,L1.COMPONENT_QTY,L1.LOT_STATE,L1.LOT_CATEGORY FROM RPTDW.LOT_MASTER_SNAPSHOT_HOUR L1 WHERE L1.RUN_TIME_DATE = TO_CHAR(TRUNC(SYSDATE-7.5/24),'YYYY-MM-DD') AND L1.RUN_TIME_HOUR <= (SELECT MAX (RUN_TIME_HOUR) FROM RPTDW.LOT_MASTER_SNAPSHOT_HOUR WHERE RUN_TIME_DATE = TO_CHAR(TRUNC(SYSDATE-7.5/24),'YYYY-MM-DD')) AND L1.LOT_NAME IN (SELECT DISTINCT L1.LOT_NAME FROM RPTDW.LOT_STEP_HISTORY L1 WHERE L1.LOT_PURPOSE LIKE 'CS%' AND L1.PRODUCT_NAME IN (SELECT PRODUCT_NAME FROM INPUT_PRODUCT_CATEGORY_MAPPING_INFO WHERE PRODUCT_CATEGORY = 'MassProduction' )))L1 GROUP BY TO_DATE (L1.RUN_TIME_DATE ,'YYYY-MM-DD')) 当前sql执行时间过长,请优化代码
08-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值