执行 Oracle 存储过程时遇到奇怪的问题

vik*_*ana 1 oracle stored-procedures

我在执行 Oracle 存储过程时遇到了一个奇怪的问题。在将选定的数据插入另一个表时,我能够选择令人不安的数据。

以下是导致问题的查询。

BEGIN
EXECUTE IMMEDIATE
'INSERT INTO STG_MEMBER_MONTH_1
(
 MEMBER_ID
,EMPLOYER_GROUP_ID
,MEMBER_BIRTH_DATE
,SPAN_FROM_DATE
,GROUP_ID_FINAL
,GROUP_SIZE
,NAME_TO_BE_USED
,MEM_DOB
,MM
,MEMBER_AGE_FINAL
,ELIG_YEAR
,ELIG_MONTH
,AGE_BAND
)
WITH CTE_Member_Month_Group_Id_Final AS (
SELECT
 a.MEMBER_ID
,a.EMPLOYER_GROUP_ID
,a.MEMBER_BIRTH_DATE
,a.SPAN_FROM_DATE
b.ACCOUNT_NUM as GROUP_ID_FINAL
from STG_MEMBER_MONTH_2 a LEFT JOIN
(SELECT DISTINCT GRP_ID,ACCOUNT_NUM from ACCOUNT_MAPPING)b
ON a.EMPLOYER_GROUP_ID= b.GRP_ID)

,CTE_Member_Month_Group_Name as (
    SELECT a.*,b.GROUP_SIZE,b.GROUP_NAME as NAME_TO_BE_USED 
    from CTE_Member_Month_Group_Id_Final  a
    LEFT JOIN APP_CALENDAR b
    ON a.GROUP_ID_FINAL= b.GROUP_ID
)
,CTE_Max_DOB AS (
     SELECT a.MEMBER_ID,b.MEMBER_BIRTH_DATE AS MEM_DOB from
       (SELECT MEMBER_ID,max(SPAN_FROM_DATE) as SPAN_FROM_DATE from CTE_Member_Month_Group_Name
        GROUP BY MEMBER_ID)
     LEFT OUTER JOIN CTE_Member_Month_Group_Name b
     ON a.MEMBER_ID = b.MEMBER_ID
     AND a.SPAN_FROM_DATE = b.SPAN_FROM_DATE)
,CTE_Age_Band_Prev AS (
     SELECT a.*,b.MEM_DOB,1 as "MM"
    ,trunc(months_between(a.SPAN_FROM_DATE,B.MEM_DOB)/12) as "MEMBER_AGE_FINAL"
    ,extract(year from a.SPAN_FROM_DATE)                  as "ELIG_YEAR"
    ,extract(month from a.SPAN_FROM_DATE)                 as "ELIG_MONTH"
    from CTE_Member_Month_Group_Name a
    LEFT OUTER JOIN CTE_Max_DOB  b
    ON a.MEMBER_ID=b.MEMBER_ID
)
,CTE_Age_Band AS (
    SELECT a.*,
    CASE
        WHEN ltrim("MEMBER_AGE_FINAL") < 1 
        THEN 'Less than one year'
        WHEN ltrim("MEMBER_AGE_FINAL") > 17 and ltrim("MEMBER_AGE_FINAL") <=29 
        THEN '18 - 29 years'
        WHEN ltrim("MEMBER_AGE_FINAL") > 29 and ltrim("MEMBER_AGE_FINAL") <=39 
        THEN '29 - 39 years'
        ELSE 'More than 40 years'
    END as "AGE_BAND"
    from CTE_Age_Band_Prev a

)
SELECT * from CTE_Age_Band';
END;
/
Run Code Online (Sandbox Code Playgroud)

我能够从CTE_Age_Band没有任何问题的情况下选择所有内容,但无法将所选数据插入到表中STG_MEMBER_MONTH_1。我收到以下错误消息

ORA-06550: LINE 57,column 1:
PLS-00103: Encountered the symbol "," when expecting one of the following:
Run Code Online (Sandbox Code Playgroud)

如果我CTE_Age_Band从上面的语句中删除了最后一个 CTE并AGE_BAND从 insert 语句中删除了列,它将在没有任何错误的情况下执行。更改后的逻辑如下所示:

BEGIN
EXECUTE IMMEDIATE
'INSERT INTO STG_MEMBER_MONTH_1
(
 MEMBER_ID
,EMPLOYER_GROUP_ID
,MEMBER_BIRTH_DATE
,SPAN_FROM_DATE
,GROUP_ID_FINAL
,GROUP_SIZE
,NAME_TO_BE_USED
,MEM_DOB
,MM
,MEMBER_AGE_FINAL
,ELIG_YEAR
,ELIG_MONTH
)
WITH CTE_Member_Month_Group_Id_Final AS (
SELECT
 a.MEMBER_ID
,a.EMPLOYER_GROUP_ID
,a.MEMBER_BIRTH_DATE
,a.SPAN_FROM_DATE
b.ACCOUNT_NUM as GROUP_ID_FINAL
from STG_MEMBER_MONTH_2 a LEFT JOIN
(SELECT DISTINCT GRP_ID,ACCOUNT_NUM from ACCOUNT_MAPPING)b
ON a.EMPLOYER_GROUP_ID= b.GRP_ID)

,CTE_Member_Month_Group_Name as (
SELECT a.*,b.GROUP_SIZE,b.GROUP_NAME as NAME_TO_BE_USED from CTE_Member_Month_Group_Id_Final  a
LEFT JOIN APP_CALENDAR b
ON a.GROUP_ID_FINAL= b.GROUP_ID
)
,CTE_Max_DOB AS (
SELECT a.MEMBER_ID,b.MEMBER_BIRTH_DATE AS MEM_DOB from
       (SELECT MEMBER_ID,max(SPAN_FROM_DATE) as SPAN_FROM_DATE from CTE_Member_Month_Group_Name
        GROUP BY MEMBER_ID)
LEFT OUTER JOIN CTE_Member_Month_Group_Name b
ON a.MEMBER_ID = b.MEMBER_ID
AND a.SPAN_FROM_DATE = b.SPAN_FROM_DATE)
,CTE_Age_Band_Prev AS (
   SELECT a.*,b.MEM_DOB,1 as "MM"
   ,trunc(months_between(a.SPAN_FROM_DATE,B.MEM_DOB)/12) as "MEMBER_AGE_FINAL"
   ,extract(year from a.SPAN_FROM_DATE)                  as "ELIG_YEAR"
   ,extract(month from a.SPAN_FROM_DATE)                 as "ELIG_MONTH"
   from CTE_Member_Month_Group_Name a
   LEFT OUTER JOIN CTE_Max_DOB  b
   ON a.MEMBER_ID=b.MEMBER_ID
)
SELECT * from CTE_Age_Band_Prev';
END;
/
Run Code Online (Sandbox Code Playgroud)

看起来最后一个 CTE ' CTE_Age_Band' 中有一些愚蠢的错误,我无法弄清楚。

Bob*_*ica 5

The problem is the string literals inside your SQL string. To have a single-quote put into the string you need to double the single quotes, i.e. put two of them side by side:

BEGIN
EXECUTE IMMEDIATE
'INSERT INTO STG_MEMBER_MONTH_1
(
 MEMBER_ID
,EMPLOYER_GROUP_ID
,MEMBER_BIRTH_DATE
,SPAN_FROM_DATE
,GROUP_ID_FINAL
,GROUP_SIZE
,NAME_TO_BE_USED
,MEM_DOB
,MM
,MEMBER_AGE_FINAL
,ELIG_YEAR
,ELIG_MONTH
,AGE_BAND
)
WITH CTE_Member_Month_Group_Id_Final AS (
SELECT
 a.MEMBER_ID
,a.EMPLOYER_GROUP_ID
,a.MEMBER_BIRTH_DATE
,a.SPAN_FROM_DATE
b.ACCOUNT_NUM as GROUP_ID_FINAL
from STG_MEMBER_MONTH_2 a LEFT JOIN
(SELECT DISTINCT GRP_ID,ACCOUNT_NUM from ACCOUNT_MAPPING)b
ON a.EMPLOYER_GROUP_ID= b.GRP_ID)

,CTE_Member_Month_Group_Name as (
    SELECT a.*,b.GROUP_SIZE,b.GROUP_NAME as NAME_TO_BE_USED 
    from CTE_Member_Month_Group_Id_Final  a
    LEFT JOIN APP_CALENDAR b
    ON a.GROUP_ID_FINAL= b.GROUP_ID
)
,CTE_Max_DOB AS (
     SELECT a.MEMBER_ID,b.MEMBER_BIRTH_DATE AS MEM_DOB from
       (SELECT MEMBER_ID,max(SPAN_FROM_DATE) as SPAN_FROM_DATE from CTE_Member_Month_Group_Name
        GROUP BY MEMBER_ID)
     LEFT OUTER JOIN CTE_Member_Month_Group_Name b
     ON a.MEMBER_ID = b.MEMBER_ID
     AND a.SPAN_FROM_DATE = b.SPAN_FROM_DATE)
,CTE_Age_Band_Prev AS (
     SELECT a.*,b.MEM_DOB,1 as "MM"
    ,trunc(months_between(a.SPAN_FROM_DATE,B.MEM_DOB)/12) as "MEMBER_AGE_FINAL"
    ,extract(year from a.SPAN_FROM_DATE)                  as "ELIG_YEAR"
    ,extract(month from a.SPAN_FROM_DATE)                 as "ELIG_MONTH"
    from CTE_Member_Month_Group_Name a
    LEFT OUTER JOIN CTE_Max_DOB  b
    ON a.MEMBER_ID=b.MEMBER_ID
)
,CTE_Age_Band AS (
    SELECT a.*,
    CASE
        WHEN ltrim("MEMBER_AGE_FINAL") < 1 
        THEN ''Less than one year''
        WHEN ltrim("MEMBER_AGE_FINAL") > 17 and ltrim("MEMBER_AGE_FINAL") <=29 
        THEN ''18 - 29 years''
        WHEN ltrim("MEMBER_AGE_FINAL") > 29 and ltrim("MEMBER_AGE_FINAL") <=39 
        THEN ''29 - 39 years''
        ELSE ''More than 40 years''
    END as "AGE_BAND"
    from CTE_Age_Band_Prev a

)
SELECT * from CTE_Age_Band';
END;
/
Run Code Online (Sandbox Code Playgroud)

  • “有点不同”?Oracle 与您有很多不同,其方式比您意识到的要多得多。它们从根本上来说是不同的。由于 RDBMS 的架构和设计的基本方式,其中一种实践的“最佳实践”往往是另一种实践的“最差实践”。相似之处以 SELECT * FROM MYTABLE 开始和结束; (2认同)