在动态表上获取“ORA00904:无效标识符”

Posted

技术标签:

【中文标题】在动态表上获取“ORA00904:无效标识符”【英文标题】:Getting 'ORA00904: invalid identifier' on dynamic tables 【发布时间】:2018-08-30 04:38:42 【问题描述】:

我有一个适用于动态表的脚本。执行下面的代码段时,它给了我错误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;

【问题讨论】:

您使用的是哪个数据库,也请分享您的表结构 由于这些oracle数据库表是动态的,KEY_VALUE列的存在与否取决于表结构。表没有唯一的结构。 您使用的是哪个数据库? 需要一些信息才能为您提供有效的解决方案。 Database_SYS.Column_Exist 函数的签名是什么? (需要了解如何将列名传递给它)。 new_key_ref_ 是两个相关表的变量还是列?它的类型是什么?假设_rec是一个变量,那么rec_.ROWID的类型是什么? 【参考方案1】:

这个会更好:

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) 应该没问题。

【讨论】:

【参考方案2】:

试试这样的:

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

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

【讨论】:

key_value 无法消除。 key_value是应该更新的主列,这就是放这个IF/ELSE块的目的。 我已经展示了您的 else 子句中提到的查询示例。您可以类似地为 if 部分创建查询【参考方案3】:
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;

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

【讨论】:

【参考方案4】:

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

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;

【讨论】:

以上是关于在动态表上获取“ORA00904:无效标识符”的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00904 无效标识符错误

ORA-00904: 无效标识符 00904. 00000 - "%s: 无效标识符"

ORACLE ORA-00904: 无效标识符错误

错误报告:SQL 错误:ORA-00904::无效标识符 00904。00000 - “%s:无效标识符”

无法使用外键创建表。错误:ORA-00904: : 无效标识符

python调用oracle函数ORA-00904无效标识符