PL SQL /Oracle 中的这个 CTE WITH 子句有什么问题?
What is the issue with this CTE WITH clause in PL SQL /Oracle?
我有以下查询。
下面的 WITH CTE 查询,它是 returning 4 Records.
正如我给出的评论,下面的 Select 查询有 55 条记录,使用 And 子句应该删除这 4 条记录和 return 51 条记录。取而代之的是 return 只是那 4 条记录。
只是为了测试,我评论了 AND 子句,然后它按预期运行并且 returning 55+4 = 总共 59 条记录。
如何使用 CTE 解决这个问题。怎么了?
CREATE OR REPLACE PROCEDURE CUSTCONNECT.sp_GetPodConfigurationGridData(
p_podURL IN varchar2, --PodUrl
p_serverType IN varchar2,
p_serverName IN varchar2,
p_publishedDate IN date,
P_RECORDSET OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN P_RECORDSET FOR
--This has total of 4 Records
WITH PodServerRecords(Key, value, Overwrite, ServerName, ServerType, PublishDate ) AS (
select
PC.KeyId as Key, KeyIdValue as value, 'Pod' as Overwrite, '' as ServerName, '' as Servertype, PC.PublishDate
from (select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigLog_Tab Keylog
where Keylog.URL = p_podURL
and Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PC
where PC.RowNu = 1 and PC.IsActive = 'T'
UNION
select
PCBS.KeyId as Key, KeyIdValue as value, 'Server' as Overwrite, PCBS.ServerName, Servertype, PCBS.PublishDate
from (select
Serlog.*, PS.ServerType, row_number() over (partition by Serlog.KeyId order by Serlog.PublishDate desc) as RowNu
from PodConfigByServerLog_Tab Serlog
join PodServer_tab PS on PS.ServerName = Serlog.ServerName
and Serlog.URL = PS.URL
where Serlog.URL = p_podURL
and Serlog.ServerName = p_serverName
and Serlog.PublishDate >= p_publishedDate and Serlog.PublishDate <= sysdate
) PCBS
where PCBS.RowNu = 1 and PCBS.IsActive = 'T'
)
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
)
UNION
--This is total of 4 Records
SELECT
Key, value, Overwrite, ServerName, ServerType, PublishDate
FROM PodServerRecords
Order By Key;
END;
/
您的问题是 CTE 没有名为 KeyId
的列。您将其重命名为 Key
。但是,当有 NULL
值时,NOT IN
会出现意外行为。您可以通过直接消除它们来解决此问题:
PCK.KeyId not in (
select psr.KeyId
from PodServerRecords psr
where psr.KeyId IS NOT NULL
)
我建议改用 NOT EXISTS
:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.KeyId = PCK.KeyId
)
这可能会解决您的问题。
实际上,我在您的 CTE 中没有看到 KeyId
。所以,我想你想要:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.Key = PCK.KeyId
)
注意前面的语句会 return 错误,表明问题出在列名错误。
我认为您应该删除查询的 UNION
部分,因为它正在从 PodServerRecords
中读取那 4 条记录。您的查询应该是
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
);
我有以下查询。 下面的 WITH CTE 查询,它是 returning 4 Records.
正如我给出的评论,下面的 Select 查询有 55 条记录,使用 And 子句应该删除这 4 条记录和 return 51 条记录。取而代之的是 return 只是那 4 条记录。
只是为了测试,我评论了 AND 子句,然后它按预期运行并且 returning 55+4 = 总共 59 条记录。
如何使用 CTE 解决这个问题。怎么了?
CREATE OR REPLACE PROCEDURE CUSTCONNECT.sp_GetPodConfigurationGridData(
p_podURL IN varchar2, --PodUrl
p_serverType IN varchar2,
p_serverName IN varchar2,
p_publishedDate IN date,
P_RECORDSET OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN P_RECORDSET FOR
--This has total of 4 Records
WITH PodServerRecords(Key, value, Overwrite, ServerName, ServerType, PublishDate ) AS (
select
PC.KeyId as Key, KeyIdValue as value, 'Pod' as Overwrite, '' as ServerName, '' as Servertype, PC.PublishDate
from (select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigLog_Tab Keylog
where Keylog.URL = p_podURL
and Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PC
where PC.RowNu = 1 and PC.IsActive = 'T'
UNION
select
PCBS.KeyId as Key, KeyIdValue as value, 'Server' as Overwrite, PCBS.ServerName, Servertype, PCBS.PublishDate
from (select
Serlog.*, PS.ServerType, row_number() over (partition by Serlog.KeyId order by Serlog.PublishDate desc) as RowNu
from PodConfigByServerLog_Tab Serlog
join PodServer_tab PS on PS.ServerName = Serlog.ServerName
and Serlog.URL = PS.URL
where Serlog.URL = p_podURL
and Serlog.ServerName = p_serverName
and Serlog.PublishDate >= p_publishedDate and Serlog.PublishDate <= sysdate
) PCBS
where PCBS.RowNu = 1 and PCBS.IsActive = 'T'
)
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
)
UNION
--This is total of 4 Records
SELECT
Key, value, Overwrite, ServerName, ServerType, PublishDate
FROM PodServerRecords
Order By Key;
END;
/
您的问题是 CTE 没有名为 KeyId
的列。您将其重命名为 Key
。但是,当有 NULL
值时,NOT IN
会出现意外行为。您可以通过直接消除它们来解决此问题:
PCK.KeyId not in (
select psr.KeyId
from PodServerRecords psr
where psr.KeyId IS NOT NULL
)
我建议改用 NOT EXISTS
:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.KeyId = PCK.KeyId
)
这可能会解决您的问题。
实际上,我在您的 CTE 中没有看到 KeyId
。所以,我想你想要:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.Key = PCK.KeyId
)
注意前面的语句会 return 错误,表明问题出在列名错误。
我认为您应该删除查询的 UNION
部分,因为它正在从 PodServerRecords
中读取那 4 条记录。您的查询应该是
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
);