oracle 中的过程中的某些 ID 不显示数据
Posted
技术标签:
【中文标题】oracle 中的过程中的某些 ID 不显示数据【英文标题】:Data is not displayed for some ID from the procedure in oracle 【发布时间】:2020-11-04 11:34:55 【问题描述】:我有一个存储过程,它带来了特定用户创建的所有数据。因此,如果一个名为 A
的用户创建了 100 条记录,当我运行此过程时,它应该带来 100 条记录。
目前它没有带来所有这 100 条记录,其中一些丢失了,我无法找出为什么会这样。
下面是我的存储过程。
create or replace PROCEDURE CHANGEREQUESTS_CREATED_GETLIST
(
P_USERNAME in CHANGEREQUESTS.CREATEDBY%type
, P_JOBID IN CLOB--VARCHAR2
, P_PAGENO IN NUMBER
, P_PAGESIZE IN NUMBER
, TOTALCOUNT OUT NUMBER
, OUTPUTTABLE OUT SYS_REFCURSOR
) AS
START_RECORD_NO NUMBER := 1;
END_RECORD_NO NUMBER := 10;
BEGIN
IF P_PAGENO IS NOT NULL AND P_PAGESIZE IS NOT NULL THEN
START_RECORD_NO := ((P_PAGENO -1) * P_PAGESIZE) +1;
END_RECORD_NO := P_PAGESIZE * P_PAGENO;
END IF;
--open TOTALCOUNT for
SELECT COUNT(*) INTO TOTALCOUNT
FROM
CHANGEREQUESTS CR
where
EXISTS ( SELECT * FROM THE ( SELECT CAST( STR2TBL( P_JOBID ) AS MYTABLETYPE ) FROM DUAL ) TT WHERE TT.COLUMN_VALUE = CR.JOBID )
--CR.JOBID in (select REGEXP_SUBSTR(P_JOBID,'[^,]+', 1, level) from DUAL connect by REGEXP_SUBSTR(P_JOBID, '[^,]+', 1, level) is not null)
and CREATEDBY = P_USERNAME
and JOBID > 0;
OPEN OUTPUTTABLE FOR
select
CHANGEREQUESTID
,DESCRIPTION
,CHANGEREQUESTNUMBER
,STATENAME
,CITYNAME
,CATEGORY
,CHANGETYPE
,STATUSID
,CREATEDBY
,OPENCLOSED
,JOBID
,CREATEDON
,LASTMODIFIEDON
from
( select
ROW_NUMBER() over ( order by CR.CHANGEREQUESTID DESC) ROWNO
,CR.CHANGEREQUESTID
,CR.DESCRIPTION
,CR.CHANGEREQUESTNUMBER
,CR.STATENAME
,CR.CITYNAME
,CC.CATEGORY
,CT.CHANGETYPE
,CR.STATUSID
,CR.CREATEDBY
,'' as OPENCLOSED
,CR.JOBID
,CR.CREATEDON
,CR.LASTMODIFIEDON
FROM
CHANGEREQUESTS CR
inner join
CHANGETYPES CT
on CR.CHANGETYPEID = CT.CHANGETYPEID
inner join
CHANGECATEGORIES CC
ON CC.CHANGECATEGORYID = CT.CHANGECATEGORYID
where
EXISTS ( SELECT * FROM THE ( SELECT CAST( STR2TBL( P_JOBID ) AS MYTABLETYPE ) FROM DUAL ) TT WHERE TT.COLUMN_VALUE = CR.JOBID )
--CR.JOBID in (select REGEXP_SUBSTR(P_JOBID,'[^,]+', 1, level) from DUAL connect by REGEXP_SUBSTR(P_JOBID, '[^,]+', 1, level) is not null)
and CREATEDBY = P_USERNAME
and JOBID > 0
--ORDER BY CR.CHANGEREQUESTID DESC
)
WHERE ROWNO >= START_RECORD_NO AND ROWNO <= END_RECORD_NO;
END CHANGEREQUESTS_CREATED_GETLIST;
下面还有表定义和所需的详细信息
`CHANGEREQUESTS`
Name Null Type
--------------------------- -------- --------------
CHANGEREQUESTID NOT NULL NUMBER(10)
CHANGEREQUESTNUMBER NOT NULL VARCHAR2(50)
CHANGETYPEID NOT NULL NUMBER(10)
NETWORKTYPE VARCHAR2(50)
STATENAME VARCHAR2(50)
CITYNAME VARCHAR2(50)
DESCRIPTION VARCHAR2(100)
REASON VARCHAR2(250)
REMARK VARCHAR2(250)
CREATEDBY NVARCHAR2(100)
CREATEDON DATE
LASTMODIFIEDBY NVARCHAR2(100)
LASTMODIFIEDON DATE
JOBID NUMBER(10)
GROUPID NUMBER(10)
STATUSID NUMBER
ISCANCELLED NOT NULL NUMBER(1)
APPLICATIONID NUMBER(10)
APPCHANGETYPE VARCHAR2(50)
CHANGEDETAILID NUMBER(10)
REQSUBMITTEDON DATE
PRIORITY VARCHAR2(50)
MODELING_CHANGE_TYPE_IDS VARCHAR2(200)
MODELING_CHANGE_DETAILS_IDS VARCHAR2(200)
DB_CHANGE_DETAIL_ID NUMBER(10)
BAND VARCHAR2(2000)
`CHANGETYPES`
Name Null Type
---------------- -------- -------------
CHANGETYPEID NOT NULL NUMBER(10)
CHANGETYPE NOT NULL VARCHAR2(250)
CHANGECATEGORYID NUMBER(10)
ISACTIVE NOT NULL NUMBER(1)
`CHANGECATEGORIES`
Name Null Type
---------------- -------- -------------
CHANGECATEGORYID NOT NULL NUMBER(10)
CATEGORY NOT NULL VARCHAR2(50)
ISACTIVE NOT NULL NUMBER(1)
更新
所以基本上我的 Oracle 版本是:- 18.3
还有,
上述过程由3个表组成,其中主列是CHANGETYPEID
,CHANGECATEGORYID
,它们已经加入了数据。
所以我的主表是CHANGEREQUESTS
,其中记录是通过连接其他两个表的 ID 获取的。
例如:-
CREATE TABLE CHANGEREQUESTS ( CHANGEREQUESTID, CHANGETYPEID, JOBID ) AS
SELECT 7835, 4, 42234 FROM DUAL UNION ALL
SELECT 7834, 22, 42233 FROM DUAL UNION ALL
SELECT 7833, 8, 42242 FROM DUAL;
CREATE TABLE CHANGETYPES (CHANGETYPEID, CHANGETYPE, CHANGECATEGORYID, ISACTIVE) AS
SELECT 8, 'Change in media type (OFC/MW)', 1, 1 FROM DUAL UNION ALL
SELECT 22, 'RF site deletion', 1, 1 FROM DUAL;
CREATE TABLE CHANGECATEGORIES ( CHANGECATEGORYID, CATEGORY, ISACTIVE ) AS
SELECT 3, 'OSP Engineering', 1 FROM DUAL UNION ALL
SELECT 2, 'Wireline', 1 FROM DUAL UNION ALL
SELECT 1, 'Wireless', 1 FROM DUAL;
【问题讨论】:
请edit您的问题有一个minimal reproducible example,包括:您的表的DDL语句(并删除不必要的列,因此每个表只有5或6列);一些样本数据的 DML 语句(我们可以复制/粘贴/执行的文本,而不是丢失一半的图像);运行代码所需的所有功能 (STR2TBL
?);您的预期输出;和您的 Oracle 版本。
当START_RECORD_NO
是0
(为什么不是1
?)和END_RECORD_NO
是10 时,当然不会得到100 行。跨度>
@MT0: 那么START_RECORD_NO
和END_RECORD_NO
应该是什么?根据你的说法应该是什么?
@MT0:我已经用每个表中的相关列及其数据更新了问题。如果需要了解其他任何内容,请告诉我。
如果您可以发布 minimal reproducible example 并使用(正如我在第一条评论中所说)我们可以复制/粘贴/执行的 DDL/DML 语句(而不是作为图像)。请帮助我们帮助您,不要期望我们输入您作为图像发布的数据。另外,请给我们一个完整的工作示例(即程序中的参数是什么以及您的示例输出的预期输出)。
【参考方案1】:
您可以通过以下方式大大简化您的程序:
测试jobid
是否是p_jobid
参数的子串;和
使用OFFSET m ROWS FETCH NEXT n ROWS ONLY
语法。
create or replace PROCEDURE CHANGEREQUESTS_CREATED_GETLIST
(
P_USERNAME IN CHANGEREQUESTS.CREATEDBY%type
, P_JOBID IN CLOB--VARCHAR2
, P_PAGENO IN NUMBER
, P_PAGESIZE IN NUMBER
, TOTALCOUNT OUT NUMBER
, OUTPUTTABLE OUT SYS_REFCURSOR
)
AS
v_size NUMBER := COALESCE( p_pagesize, 10 );
v_start NUMBER := COALESCE( p_pageno - 1, 0 ) * v_size;
BEGIN
SELECT COUNT(*) INTO TOTALCOUNT
FROM CHANGEREQUESTS CR
WHERE ',' || p_jobid || ',' LIKE '%,' || jobid || ',%'
AND CREATEDBY = P_USERNAME
AND JOBID > 0;
OPEN OUTPUTTABLE FOR
SELECT CR.CHANGEREQUESTID
,CT.CHANGETYPE
,CR.JOBID
FROM CHANGEREQUESTS CR
INNER JOIN CHANGETYPES CT
ON ( CR.CHANGETYPEID = CT.CHANGETYPEID )
INNER JOIN CHANGECATEGORIES CC
ON ( CC.CHANGECATEGORYID = CT.CHANGECATEGORYID )
WHERE ',' || p_jobid || ',' LIKE '%,' || jobid || ',%'
AND CREATEDBY = P_USERNAME
AND JOBID > 0
ORDER BY CR.CHANGEREQUESTID DESC
OFFSET v_start ROWS
FETCH NEXT v_size ROWS ONLY;
END CHANGEREQUESTS_CREATED_GETLIST;
/
其中,对于样本数据:
CREATE TABLE CHANGEREQUESTS ( CHANGEREQUESTID, CHANGETYPEID, JOBID, CREATEDBY ) AS
SELECT 7835, 4, 42234, 'user1' FROM DUAL UNION ALL
SELECT 7834, 22, 42233, 'user1' FROM DUAL UNION ALL
SELECT 7833, 8, 42242, 'user1' FROM DUAL UNION ALL
SELECT LEVEL,
DECODE( MOD( LEVEL, 3), 0, 4, 1, 22, 8 ),
99999,
'user1'
FROM DUAL
CONNECT BY LEVEL <= 40;
CREATE TABLE CHANGETYPES (CHANGETYPEID, CHANGETYPE, CHANGECATEGORYID, ISACTIVE) AS
SELECT 4, 'Random Type', 1, 1 FROM DUAL UNION ALL
SELECT 8, 'Change in media type (OFC/MW)', 1, 1 FROM DUAL UNION ALL
SELECT 22, 'RF site deletion', 1, 1 FROM DUAL;
CREATE TABLE CHANGECATEGORIES ( CHANGECATEGORYID, CATEGORY, ISACTIVE ) AS
SELECT 3, 'OSP Engineering', 1 FROM DUAL UNION ALL
SELECT 2, 'Wireline', 1 FROM DUAL UNION ALL
SELECT 1, 'Wireless', 1 FROM DUAL;
然后:
DECLARE
v_pgsz NUMBER := 20;
BEGIN
FOR v_pgno IN 1 .. 3 LOOP
DECLARE
v_cur SYS_REFCURSOR;
v_size NUMBER;
v_crid CHANGEREQUESTS.CHANGEREQUESTID%TYPE;
v_ctyp CHANGETYPES.CHANGETYPE%TYPE;
v_jid CHANGEREQUESTS.JOBID%TYPE;
BEGIN
CHANGEREQUESTS_CREATED_GETLIST( 'user1', '42234,99999', v_pgno, v_pgsz, v_size, v_cur );
DBMS_OUTPUT.PUT_LINE( 'Page:' || v_pgno || ' (Total: ' || v_size || ' rows)' );
LOOP
FETCH v_cur INTO v_crid, v_ctyp, v_jid;
EXIT WHEN v_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(
LPAD( v_crid, 4, ' ' ) || ' | ' ||
RPAD( v_ctyp, 30, ' ' ) || ' | ' ||
LPAD( v_jid, 4, ' ' )
);
END LOOP;
CLOSE v_cur;
END;
END LOOP;
END;
/
输出:
Page:1 (Total: 41 rows)
7835 | Random Type | 4223
40 | RF site deletion | 9999
39 | Random Type | 9999
38 | Change in media type (OFC/MW) | 9999
37 | RF site deletion | 9999
36 | Random Type | 9999
35 | Change in media type (OFC/MW) | 9999
34 | RF site deletion | 9999
33 | Random Type | 9999
32 | Change in media type (OFC/MW) | 9999
31 | RF site deletion | 9999
30 | Random Type | 9999
29 | Change in media type (OFC/MW) | 9999
28 | RF site deletion | 9999
27 | Random Type | 9999
26 | Change in media type (OFC/MW) | 9999
25 | RF site deletion | 9999
24 | Random Type | 9999
23 | Change in media type (OFC/MW) | 9999
22 | RF site deletion | 9999
Page:2 (Total: 41 rows)
21 | Random Type | 9999
20 | Change in media type (OFC/MW) | 9999
19 | RF site deletion | 9999
18 | Random Type | 9999
17 | Change in media type (OFC/MW) | 9999
16 | RF site deletion | 9999
15 | Random Type | 9999
14 | Change in media type (OFC/MW) | 9999
13 | RF site deletion | 9999
12 | Random Type | 9999
11 | Change in media type (OFC/MW) | 9999
10 | RF site deletion | 9999
9 | Random Type | 9999
8 | Change in media type (OFC/MW) | 9999
7 | RF site deletion | 9999
6 | Random Type | 9999
5 | Change in media type (OFC/MW) | 9999
4 | RF site deletion | 9999
3 | Random Type | 9999
2 | Change in media type (OFC/MW) | 9999
Page:3 (Total: 41 rows)
1 | RF site deletion | 9999
db小提琴here
【讨论】:
@hud 我正在使用答案中的内容。只有 1 个过程,然后有一个匿名 PL/SQL 块,它在循环中调用第 1、2 和 3 页的过程并显示输出。您可以检查底部的 dbfiddle 链接以查看它正在运行。你不需要那个匿名的 PL/SQL 块,它只是用来演示调用函数。 @hud 链接的 dbfiddle 的程序运行没有错误(在 Oracle 18 中);请逐行检查并检查您的语法是否正确,因为您的代码与我的代码不同(运行时没有错误)。 我正在使用这个dbfiddle.uk/…,它给了我错误。不明白我错过了什么 它几乎肯定会在 Oracle 19 中工作,因为 Oracle 与以前的版本兼容。但是,dbfiddle 只为 Oracle 11gR2 和 Oracle 18 提供环境。如果你想在 Oracle 19 上测试它,那么你要么需要你自己的本地环境,要么去livesql.oracle.com 并在那里运行它。 请看前面评论中的 dbfiddle。它通过修复前几个错误并获取错误消息来告诉您下一个问题是什么......但是,所有错误都与缺少的尾随/
相关(之后必须在其自己的一行上)程序结束)并且您缺少表格。以上是关于oracle 中的过程中的某些 ID 不显示数据的主要内容,如果未能解决你的问题,请参考以下文章