分享
三行代码  ›  专栏  ›  技术社区  ›  Станислав Китаев

动态选择中的标识符无效

  •  0
  • Станислав Китаев  · 技术社区  · 1 周前

    我有一个小程序,应该截断分区,如果存在

    create or replace PROCEDURE                 drop_partition(p_table_name VARCHAR2, p_load_seq INTEGER)
    AS
            l_sql_text         VARCHAR2(1000 CHAR);
            l_part_exists      NUMBER;
    BEGIN
            l_sql_text:= 'SELECT count(*) FROM  user_tab_partitions where table_name=' || p_table_name ||' and high_value='||p_load_seq ;
            EXECUTE IMMEDIATE l_sql_text INTO l_part_exists;
            if (l_part_exists=1) THEN
            l_sql_text := 'ALTER TABLE ' || p_table_name || ' DROP PARTITION FOR(' || to_char(p_load_seq) || ')';
            EXECUTE IMMEDIATE l_sql_text;
            END IF;
    END;
    

    如果我试着运行这样的程序

    call drop_partition('test',1);
    

    ORA-00904: "TEST": invalid identifier
    ORA-06512: at "DROP_PARTITION", line 8
    00904. 00000 -  "%s: invalid identifier"
    

    问题是什么?我如何解决?

    1 回复  |  直到 1 周前
        1
  •  2
  •   Alex Poole    1 周前

    您需要用单引号将表名括起来,您需要对其进行转义:

    ... where table_name=''' || p_table_name ||''' and ...
    

    l_sql_text:= 'SELECT count(*) FROM  user_tab_partitions where table_name=''' || p_table_name ||''' and high_value='||p_load_seq ;
    

    有一个 alternative quoting mechanism 这样就不需要对引号进行转义,但我认为这里会更加混乱。

    默认情况下,在数据字典中,像表名这样的标识符是大写的,所以您可以这样做 upper(p_table_name)

    drop_partition('TEST', 1);
    

    ... 假设你 test 表没有带引号的标识符。

    使用动态SQL时,在执行生成的语句之前,为了调试目的,可以先输出它:

    dbms_output.put_line(l_sql_text);