oracle 通过 shell 脚本和 sqlplus 改变序列

oracle alter sequence by shell script & sqlplus

我正在 shell 脚本中通过 sqlplus 更改序列。 我要做的是获取 table 的最大值 seq_no,在 v_increment_num 中设置值,并将序列增加 v_increment_num。但是在alter语句运行的时候会报错

脚本如下。

echo start load_my_adm_user.sh

sqlplus myId/myPassword <<EOF

set echo on
set time on
set timing on
set serveroutput on
spool TB_MY_ADM_USER.log

var v_increment_num varchar2(1000);

SELECT MAX(SEQ_NO) INTO :v_increment_num FROM TB_MY_ADM_USER;
alter sequence mydb.SQ_ADM_USER increment by v_increment_num;
select mydb.SQ_ADM_USER.nextval from dual;
alter sequence mydb.SQ_ADM_USER increment by 1;

spool off
EOF
exit

并且 运行 结果 (TB_MY_ADM_USER.log) 就像:

07:01:23 SQL> SELECT MAX(SEQ_NO) INTO :v_increment_num FROM TB_MY_ADM_USER;

MAX(SEQ_NO)
-----------
          4

Elapsed: 00:00:00.00
07:01:23 SQL>
07:01:23 SQL> alter sequence mydb.SQ_ADM_USER increment by v_increment_num;
alter sequence mydb.SQ_ADM_USER increment by v_increment_num
                                                  *
ERROR at line 1:
ORA-01722: invalid number


Elapsed: 00:00:00.00
07:01:23 SQL>
07:01:23 SQL> select mydb.SQ_ADM_USER.nextval from dual;

   NEXTVAL
----------
        19

Elapsed: 00:00:00.02
07:01:23 SQL> alter sequence mydb.SQ_ADM_USER increment by 1;

Sequence altered.

Elapsed: 00:00:00.02

我到底做错了什么? 提前致谢。

您几乎所有事情都是正确的,只需要记住 DDL 语句,即 alter sequence,也不适用于绑定变量。其中,我的意思是一个绑定变量,就是你的 v_increment_num 是什么。

如果 SQL*Plus 是您要使用的,请尝试使用它自己的替换 "variables",即 "ampersand"-变量...

echo start load_my_adm_user.sh

sqlplus myId/myPassword <<EOF

set echo on
set time on
set timing on
set serveroutput on
spool TB_MY_ADM_USER.log

-- do not do...
-- var v_increment_num varchar2(1000);
-- do instead...
column max_seq_no new_val v_increment_num
-- note: this makes all MAX_SEQ_NO column values from all subsequent SELECTs to be stored in the &V_INCREMENT_NUM variable

-- do not do...
-- SELECT MAX(SEQ_NO) INTO :v_increment_num FROM TB_MY_ADM_USER;
-- do instead...
SELECT MAX(SEQ_NO) as max_seq_no FROM TB_MY_ADM_USER;
-- note: at this point, you will have your MAX(SEQ_NO) value stored in your &V_INCREMENT_NUM variable

-- do not do...
-- alter sequence mydb.SQ_ADM_USER increment by v_increment_num;
-- do instead...
alter sequence mydb.SQ_ADM_USER increment by &v_increment_num;

select mydb.SQ_ADM_USER.nextval from dual;
alter sequence mydb.SQ_ADM_USER increment by 1;

spool off
EOF
exit

注意:我没有尝试这个特定的代码,只是直接写在这里,所以它可能在第一次尝试时不起作用,但我们会解决这个问题稍后出来。