PL/SQL动态SQL:表名无效
我目前正在学习PL/SQL。我需要创建一个PL/SQL块来创建我所有表的备份,如下所示:myTable->myTable\u old 我现在得到的是:PL/SQL动态SQL:表名无效,sql,oracle,plsql,dynamic-sql,Sql,Oracle,Plsql,Dynamic Sql,我目前正在学习PL/SQL。我需要创建一个PL/SQL块来创建我所有表的备份,如下所示:myTable->myTable\u old 我现在得到的是: DECLARE Cursor c IS SELECT table_name FROM user_tables WHERE table_name NOT LIKE '%_old'; sql_slc VARCHAR2(200); sql_drp VARCHAR2(200); sql_crt VARC
DECLARE
Cursor c IS SELECT table_name
FROM user_tables
WHERE table_name NOT LIKE '%_old';
sql_slc VARCHAR2(200);
sql_drp VARCHAR2(200);
sql_crt VARCHAR2(200);
row_count NUMBER;
t_name user_tables.table_name%type;
t_backup_name user_tables.table_name%type;
BEGIN
sql_drp := 'DROP TABLE :1 CASCADE';
sql_crt := 'CREATE TABLE :1 AS SELECT * FROM :2';
sql_slc := 'SELECT COUNT(*) FROM user_tables WHERE table_name = :1';
OPEN c;
LOOP
FETCH c INTO t_name;
EXIT WHEN (c%NOTFOUND);
t_backup_name := t_name || '_old';
dbms_output.put_line(t_name || ' ' || t_backup_name);
EXECUTE IMMEDIATE sql_slc INTO row_count USING t_backup_name;
IF row_count > 0 THEN
dbms_output.put_line(t_backup_name || ' dropped');
EXECUTE IMMEDIATE sql_drp USING t_backup_name;
END IF;
dbms_output.put_line(t_backup_name || ' created');
EXECUTE IMMEDIATE sql_crt USING t_backup_name, t_name;
COMMIT;
END LOOP;
CLOSE c;
END;
/
以下是错误:
OUVRAGE OUVRAGE_old
OUVRAGE_old created
DECLARE
*
ERROR on line 1 :
ORA-00903: table name not valid
ORA-06512: on line 29
我不明白为什么会出现这个错误,有人能帮我吗?问题是不能将绑定变量用于表名;: 数据库专门使用绑定变量的值,并且 不以任何方式解释其内容 您应该编辑代码以使用串联:
DECLARE
Cursor c IS SELECT table_name
FROM user_tables
WHERE table_name NOT LIKE '%_OLD'; /* OLD, upper case */
sql_slc VARCHAR2(200);
--sql_drp VARCHAR2(200);
--sql_crt VARCHAR2(200);
row_count NUMBER;
t_name user_tables.table_name%type;
t_backup_name user_tables.table_name%type;
BEGIN
-- sql_drp := 'DROP TABLE :1 CASCADE';
-- sql_crt := 'CREATE TABLE :1 AS SELECT * FROM :2';
sql_slc := 'SELECT COUNT(*) FROM user_tables WHERE table_name = :1';
OPEN c;
LOOP
FETCH c INTO t_name;
EXIT WHEN (c%NOTFOUND);
t_backup_name := t_name || '_OLD'; /* OLD, upper case */
DBMS_OUTPUT.put_line (t_name || ' ' || t_backup_name);
EXECUTE IMMEDIATE sql_slc INTO row_count USING t_backup_name;
IF row_count > 0
THEN
DBMS_OUTPUT.put_line (t_backup_name || ' dropped');
-- EXECUTE IMMEDIATE sql_drp USING t_backup_name;
EXECUTE IMMEDIATE ' drop table ' || t_backup_name; /* concatenation and not bind variables */
END IF;
DBMS_OUTPUT.put_line (t_backup_name || ' created'); /* concatenation and not bind variables */
-- EXECUTE IMMEDIATE sql_crt USING t_backup_name, t_name;
EXECUTE IMMEDIATE 'create table ' || t_backup_name || ' as select * from ' || t_name;
COMMIT;
END LOOP;
CLOSE c;
END;
另外,请注意,如果不是双引号,对象名称总是大写的,因此您必须查找
t|u name | |“| OLD”
,而不是t|u name | | |“| OLD”
,因为t|u name的长度约为32,所以添加“| u OLD”可能会导致它太长而无法被数据库接受。(取决于db版本)它崩溃的下一个表的名称是“AUTUR_OUVRAGE”,如果添加,它的长度仍然低于VARCHAR2(30)。。。我仍然尝试将t_name和t_backup_name更改为VARCHAR2(30),但没有更改任何内容。我看到第29行出现错误,但仍然尝试注释掉第一个execute immediate语句并再次运行该块。让我们看看错误发生的位置如果行计数>0,它会在第二次执行(删除)时崩溃,每次都会在第三次执行(创建表)时崩溃。然后再进行一次测试。将最后一个“立即执行”替换为以下使用t\u backup\u name、t\u name开始执行立即sql\u crt;当其他人然后dbms_输出.put_行('t_backup_name:'| t|u backup_name | t|u name:'| t|u name)时出现异常;返回;结束;让我们看看它输出了什么