2014-04-03 83 views
1

我在VBA中访问ORACLE DB时有以下语句。我的问题是,当我运行查询,我收到我的左的错误加盟:左连接错误

错误ORA-00904无效的标识符0100650.EEM_ID

我百思不得其解,因为我已经创建了类似于其他查询这没有问题。任何援助将不胜感激。谢谢!

SQLStr = "SELECT * FROM (SELECT LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' '))), NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' '), LENGTH((NVL(O100668.EMAIL_ADDRESS,' '))), NVL(O100668.EMAIL_ADDRESS,' '), O100650.FIRST_NAME, O100659.ID, O100650.LAST_NAME, O100650.PERSON_CODE, O100650.PRIME_ASSIGNMENT, (P2K.P2K_SMGCD(O100650.DES_ID,'DES')), (P2K.P2K_SMGCD(O100564.BPN_ID,'BPN')), " & _ 
" row_number() over (partition by O100650.PERSON_CODE order by O100650.PERSON_CODE ASC, O100650.PRIME_ASSIGNMENT ASC) rn " & _ 
"FROM P2K.P2K_BE_ENROLLMENTS O100564, P2K.P2K_BE_ENROLLMENT_DETAILS O100567, P2K.P2K_HR_VSASSIGNMENTS O100650, P2K.P2K_HR_EMPLOYMENTS O100659, P2K.P2K_HR_PERSONALS O100668 " & _ 
"LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564 on (O100564.EEM_ID = O100659.ID and O100564.BPN_ID=148) " & _ 
"WHERE ((O100650.EEM_ID = O100659.ID) AND (O100564.ID = O100567.BEN_ID) AND (O100650.EEM_ID = O100564.EEM_ID) AND (O100650.EID_ID = O100668.EID_ID)) AND ((P2K.P2K_SMGCD(O100650.DES_ID,'DES')) IN ('ACTIVE','PENDING')) AND ((LENGTH((NVL(O100668.EMAIL_ADDRESS,' ')))) >= 3) AND (( ((LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ')))) <= 3 OR (NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ')) IS NULL ) )) AND (TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY) AND (SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY) AND (SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY)) " & _ 
"WHERE rn=1 " & _ 
"ORDER BY O100650.LAST_NAME ASC ;" 
+1

您是否尝试过生成的字符串并通过SQL客户端运行该字符串? – OldProgrammer

+0

你所做的不仅仅是一个语法错误,而是你正在将你的左连接改变为一个内连接。 http://wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN – HLGEM

+0

更改语句使用正确的标识符,现在我收到一个错误ORA-00920请求任何建议。此外,尝试使用下面的一些例子,他们犯了错误。 – user3297770

回答

0

看看左连接线和最后一行。语法错误在那里。

SELECT * 
FROM (
    SELECT LENGTH((NVL(O100668.EMAIL_ADDRESS,' '))) 
     , LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' '))) 
     , NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') 
     , NVL(P2K.P2K_SMGETUDF('P2K_HR_PERSONALS','HOME EMAIL',O100668.ID),' ') 
     , NVL(O100668.EMAIL_ADDRESS,' ') 
     , O100650.FIRST_NAME 
     , O100659.ID 
     , O100650.LAST_NAME 
     , O100650.PERSON_CODE 
     , (P2K.P2K_SMGCD(O100650.DES_ID,'DES')) 
     , (P2K.P2K_SMGCD(O100564.BPN_ID,'BPN')) 
     , row_number() over (partition by O100650.PERSON_CODE order by O100650.PERSON_CODE ASC) rn 
     FROM P2K.P2K_BE_ENROLLMENTS O100564 
      , P2K.P2K_BE_ENROLLMENT_DETAILS O100567 
      , P2K.P2K_HR_VSASSIGNMENTS O100650 
      , P2K.P2K_HR_EMPLOYMENTS O100659 
      , P2K.P2K_HR_PERSONALS O100668 
     LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564 
      on (0100564.EEM_ID = O100659.ID and 0100564.BPN_ID=148) & <--- this doesn't make sense 
    WHERE ((O100650.EEM_ID = O100659.ID) 
     AND (O100564.ID = O100567.BEN_ID) 
     AND (O100650.EEM_ID = O100564.EEM_ID) 
     AND (O100650.EID_ID = O100668.EID_ID)) 
     AND ((P2K.P2K_SMGCD(O100650.DES_ID,'DES')) IN ('ACTIVE','PENDING')) 
     AND ((LENGTH((NVL(O100668.EMAIL_ADDRESS,' ')))) >= 3) 
     AND (( ((LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ')))) <= 3 OR (NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ')) IS NULL ) )) 
     AND (TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY) 
     AND (SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY) 
     AND (SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY)) 

WHERE rn=1ORDER BY O100650.LAST_NAME ASC ; <---there is no sapce after the 1 
0

我看到你在0100564.EEM_ID = O100659.ID加盟,但你必须O100650.EEM_ID = O100564.EEM_ID您的where子句。这让我觉得你想要的ID是0100659而不是EEM_ID。

1

我冒昧地将你的笛卡尔产品改写成可读的东西,有些是难以辨认的东西。应避免使用旧连接样式,只需指定每个连接条件并将所有需要的逻辑添加到每个JOIN条件而不是where子句。这实际上可以提高性能,因为服务器能够更好地利用索引。

SELECT * 
    FROM (
      SELECT LENGTH((NVL(O100668.EMAIL_ADDRESS, ' '))) 
       ,LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' '))) 
       ,NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ') 
       ,NVL(P2K.P2K_SMGETUDF('P2K_HR_PERSONALS', 'HOME EMAIL', O100668.ID), ' ') 
       ,NVL(O100668.EMAIL_ADDRESS, ' ') 
       ,O100650.FIRST_NAME 
       ,O100659.ID 
       ,O100650.LAST_NAME 
       ,O100650.PERSON_CODE 
       ,(P2K.P2K_SMGCD(O100650.DES_ID, 'DES')) 
       ,(P2K.P2K_SMGCD(O100564.BPN_ID, 'BPN')) 
       ,ROW_NUMBER() OVER (PARTITION BY O100650.PERSON_CODE ORDER BY O100650.PERSON_CODE ASC) rn 
      FROM P2K.P2K_HR_VSASSIGNMENTS O100650 
      JOIN P2K.P2K_BE_ENROLLMENTS O100564 
       ON O100650.EEM_ID = O100564.EEM_ID 
      JOIN P2K.P2K_HR_PERSONALS O100668 
       ON O100650.EID_ID = O100668.EID_ID 
        AND (SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY) 
        AND ((LENGTH((NVL(O100668.EMAIL_ADDRESS, ' ')))) >= 3) 
      JOIN P2K.P2K_HR_EMPLOYMENTS O100659 
       ON O100650.EEM_ID = O100659.ID 
        AND (( ((LENGTH((NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ')))) <= 3 
         OR (NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ')) IS NULL ) ) 
         ) 
      JOIN P2K.P2K_BE_ENROLLMENT_DETAILS O100567 
       ON O100564.ID = O100567.BEN_ID 
        AND (SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY) 
      LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564 
       ON O100659.ID = O100564.EEM_ID 
        AND O100564.BPN_ID = 148 
      WHERE (TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY) 
       AND ((P2K.P2K_SMGCD(O100650.DES_ID, 'DES')) IN ('ACTIVE', 'PENDING')) 
     ) 
    WHERE rn = 1 
    ORDER BY O100650.LAST_NAME ASC;