create or replace procedure kingway.PIS_sequence2(tablename  varchar2,
                                                  columnname varchar2) as
  strsql varchar2(1000);
begin
  strsql := 'create sequence kingway.seq_' || tablename ||
            ' minvalue 1 maxvalue 
999999 start with 1 increment by 1 nocache';
  execute immediate strsql;
  strsql := 'create or replace trigger kingway.trg_' || tablename || ' before insert on 
            ' || tablename || ' for each row 
                    begin SELECT CONCAT(
                    TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS'),
                    LPAD(seq_' || tablename ||'.nextval,6,'0')) 
                     into :new.' || columnname || ' FROM dual;end;';
  execute immediate strsql;
end;
执行就报出
PROCEDURE KINGWAY.PIS_SEQUENCE2 编译错误错误:PLS-00103: Encountered the symbol "DDMMYYYYHHMISS" when expecting one of the following:
       
          . ( * @ % & = - + ; < / > at in is mod not rem
          <an exponent (**)> <> or != or ~= >= <= <> and or like
          between ||
       The symbol ". was inserted before "DDMMYYYYHHMISS" to continue.
行:12
文本:TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS'),错误:PLS-00103: Encountered the symbol "0" when expecting one of the following:
       
          . ( * @ % & = - + ; < / > at in is mod not rem
          <an exponent (**)> <> or != or ~= >= <= <> and or like
          between ||
       The symbol ". was inserted before "0" to continue.
行:13
文本:LPAD(seq_' || tablename ||'.nextval,6,'0'))
而分组实验中
1 SQL> SELECT CONCAT(TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS'),LPAD(seq_transorder.nextval,6,'0')) FROM dual; 
正常执行如下CONCAT(TO_CHAR(SYSDATE,'DDMMYY
------------------------------
290720060924180000022 如下过程则也可以安全编译通过
create or replace procedure system.pr_CreateIdentityColumn(tablename  varchar2,
                                                    columnname varchar2) as
  strsql varchar2(1000);
begin
  strsql := 'create sequence seq_' || tablename ||
            ' minvalue 1 maxvalue 999999999999999999 start with 1 increment by 1 nocache';
  execute immediate strsql;
  strsql := 'create or replace trigger trg_' || tablename ||
            ' before insert on ' || tablename ||
            ' for each row begin select seq_' || tablename ||
            '.nextval into :new.' || columnname || ' from dual; end;';
  execute immediate strsql;
end;
痛苦啊,大虾帮助!!

解决方案 »

  1.   

    动态sql中,原来的一个单引号要写成两个单引号
      

  2.   

    TO_CHAR(SYSDATE, ''DDMMYYYYHHMISS'')试试
      

  3.   

    浪费啊,接分了。如NinGoo(蚂蚁啃大象) 说。
      'select ''12''||''bbb'' from dual'
    用两个代替一个。
      

  4.   

    动态sql中,原来的一个单引号要写成两个单引号
      

  5.   


    show error;
    这个命令来看看具体哪个地方错。
      

  6.   

    谢谢各位!但这个问题好像 也不那么简单,如NinGoo(蚂蚁啃大象) 说,动态sql中,原来的一个单引号要写成两个单引号:
    SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_' || tablename || '.nextval,6,"0")) 过程编译通过,但仍然有隐含错误:也就是执行
    exec PIS_sequence2('sdspdept','deptid');后,创建的触发器kingway.trg_sdspdept
    代码如下:
    create or replace trigger trg_sdspdept before insert on 
    TransSeq for each row 
    begin 
    SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_TransSeq.nextval,6,"0")) 
                                                 into :new.SeqNo FROM dual;end;
    编译报错:
    TRIGGER KINGWAY.TRG_TRANSSEQ 编译错误错误:PL/SQL: ORA-00904: "0": invalid identifier
    行:4
    文本:SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_TransSeq.nextval,6,"0"))错误:PL/SQL: SQL Statement ignored
    行:4
    文本:SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_TransSeq.nextval,6,"0"))//////////////////////////////////then what is wrong :(PIS_sequence2:代码如下
    create or replace procedure PIS_sequence2(tablename  varchar2,
                                              columnname varchar2) as
      strsql varchar2(1000);
    begin
      strsql := 'create sequence kingway.seq_'|| tablename ||
                ' minvalue 1 maxvalue 
    999999 start with 1 increment by 1 nocache';
      execute immediate strsql;
      strsql := 'create or replace trigger kingway.trg_' || tablename || ' before insert on 
    ' || tablename || ' for each row 
    begin 
    SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_' || tablename || '.nextval,6,"0")) 
                                                 into :new.' || columnname || ' FROM dual;end;';
      execute immediate strsql;
    end;
      

  7.   

    动态sql中,原来的一个单引号要写成两个单引号SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_TransSeq.nextval,6,"0"))
    在oracle中,你不可以采用双引号,也用单引号
    SELECT CONCAT(TO_CHAR(SYSDATE, 'DDMMYYYYHHMISS'),LPAD(seq_TransSeq.nextval,6,'0'))
      

  8.   

    字符串(varchar2)类型的用两个单引号''xxx'', 其他类型直接写
      

  9.   

    SELECT CONCAT(TO_CHAR(SYSDATE, "DDMMYYYYHHMISS"),LPAD(seq_' || tablename || '.nextval,6,"0")) 应该是
    SELECT CONCAT(TO_CHAR(SYSDATE, ''DDMMYYYYHHMISS''),LPAD(seq_' || tablename || '.nextval,6,''0'')) 我说的清清楚楚明明白白,后面N位老兄也copy,paster了好几次,你还是把两个单引号写成了一个双引号-_-!
      

  10.   

    my god ,为什么,两个单引号不等于一个双引号阿,呵呵:)饿地神哪
      

  11.   

    这个问题大概是这样的,oracle在存储过程中有两种执行sql语句的方法,他们在编写时有所区别.
    1.在oracle的存储过程中可以直接执行sql语句,这时的书写规则和sqlplus中完全相同。
    如:
    begin
    select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') from dual;
    end;2.在oracle的存储过程中通过“execute immediate sql_string;”的方式执行拼接好的sql语句,这时在拼接sql语句时要注意对单引号(')的转义,转义字符为单引号('),这就是为什么要用两个单引号代替一个单引号的原因。
    如:
    declare
      strsql varchar(4000);
    begin
      strsql := 'select to_char(sysdate,''YYYY-MM-DD HH24:MI:SS'') from dual';
      execute immediate strsql;
    end;