在动态表上获取 'ORA00904: invalid identifier'

Getting 'ORA00904: invalid identifier' on dynamic tables

我有一个用于动态表的脚本。执行下面的代码段时,它给我错误 ORA00904: invalid identifier

IF Database_SYS.Column_Exist (service_tab_, ''KEY_VALUE'') THEN                           
   UPDATE '|| service_tab_ || '
   SET key_ref    = new_key_ref_,                                  
   key_value  = ''Test'',                                  
   rowversion = SYSDATE
   WHERE ROWID    = rec_.ROWID;                                                      
ELSE                                              
   UPDATE '|| service_tab_ || '
   SET key_ref    = new_key_ref_,                               
   rowversion = SYSDATE
   WHERE ROWID    = rec_.ROWID;                           
END IF;

尝试这样的事情:

EXECUTE IMMEDIATE 'update' ||  service_tab_ || 'SET key_ref    = ' ||new_key_ref_|| ' rowversion = SYSDATE   WHERE ROWID    = '|| rec_.ROWID;

如果您遇到更多错误,请告诉我,我们可以在评论中一起解决。

BEGIN
    IF Database_SYS.Column_Exist (service_tab_, '''' || KEY_VALUE || '''') -- 4x': StartString + Quote + ' + EndString  doublepipe to concat Strings
    THEN
        EXECUTE IMMEDIATE -- If you want to Build dynamic SQL you have to throw it into "EXECUTE IMMEDIATE 'myQuery'"
            'UPDATE ' || service_tab_ || '
                SET key_ref    = new_key_ref_,
                    key_value  = ''TEST'',
                    rowversion = SYSDATE
              WHERE ROWID    = rec_.ROWID';
    ELSE
        EXECUTE IMMEDIATE
            'UPDATE ' || service_tab_ || '
                SET key_ref    = new_key_ref_,
                    rowversion = SYSDATE
              WHERE ROWID    = rec_.ROWID';
    END IF;
END;

下次您应该逐步构建您的脚本。与一堆无效代码相比,单个错误可以更好地处理..

这个会更好:

BEGIN
    IF Database_SYS.Column_Exist (service_tab_, '''' || KEY_VALUE || '''') THEN
        EXECUTE IMMEDIATE 
            'UPDATE ' || service_tab_ || '
                SET key_ref    = new_key_ref_,
                    key_value  = :val,
                    rowversion = SYSDATE
              WHERE ROWID    = :rid'
        USING 'TEST', rec_.ROWID;
    ELSE
        EXECUTE IMMEDIATE
            'UPDATE ' || service_tab_ || '
                SET key_ref    = new_key_ref_,
                    rowversion = SYSDATE
              WHERE ROWID    = :rid'
        USING rec_.ROWID;
    END IF;
END;

我认为你不需要 '''' || KEY_VALUE || '''',如果你正确地编写了函数代码,只使用 Database_SYS.Column_Exist(service_tab_, KEY_VALUE) 应该没问题。

如果唯一的区别在于更新列,则仅将条件应用于查询的一部分会更正确

DECLARE
    V_QUERY VARCHAR2(200);
BEGIN
    --
    V_QUERY := 'UPDATE '||service_tab_||
               '   SET key_ref    = new_key_ref_,              
                     rowversion = SYSDATE';
  --
    IF Database_SYS.Column_Exist (service_tab_, 'KEY_VALUE') THEN   
    V_QUERY := V_QUERY||', key_value  = ''Test''';
  END IF;
  --
  V_QUERY := V_QUERY||' WHERE ROWID    = rec_.ROWID';
  --
  EXECUTE IMMEDIATE V_QUERY;
  --
END;