为什么变量名称被其值导致" ' XXX'应该宣布"错误?

时间:2017-04-01 18:59:26

标签: variables plsql compiler-errors sqlplus identifier

我编写了以下PL / SQL块:

declare 
    v_name varchar2(20);
    v_sal integer;
begin
    EXECUTE IMMEDIATE ('CREATE TABLE EMP5 (name varchar2(20),sal integer,primary key(name))');
    dbms_output.put_line('Enter name : ');
    v_name:=&v_name;
    dbms_output.put_line('salary : ');
    v_sal :=&v_sal;
    insert into emp5 (name,sal) values (v_name,v_sal);
end;
/

然后我得到了以下编译器输出:

Enter a valeur for v_name : dhia
old 6 : v_name:=&v_name;
new 6 : v_name:=dhia;
Enter a valeur for v_sal : 10
old 8 : v_sal :=v_&sal;
new 8 : v_sal :=10;
v_name:=dhia;
      *
ERREUR at line 6 :
ORA-06550: line 6, colon 7 :
PLS-00201: the identifier 'DHIA' should be declared
ORA-06550: line 6, colon 1 :
PL/SQL: Statement ignored
ORA-06550: line9, colon 13 :
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, colon 1 :
PL/SQL: SQL Statement ignored

我的问题是为什么变量' name'取而代之的是它的价值' dhia'在脚本中导致该错误,以及如何解决它?

2 个答案:

答案 0 :(得分:0)

您不应该以这种方式使用变量,预期的行为是用它们的值替换它们,您的变量不应该与列名相同,请尝试以下操作:

declare 
varName varchar2(20);
varSal integer;
sql_stmt varchar2(200);
begin
EXECUTE IMMEDIATE ('CREATE TABLE EMP5 (name varchar2(20),sal integer,primary key(name))');
dbms_output.put_line('Enter name : ');
varName :=&varName;
dbms_output.put_line('salary : ');
varSal :=&varSal;
sql_stmt := 'INSERT INTO EMP5 VALUES (:1, :2)';
EXECUTE IMMEDIATE sql_stmt USING varName, varSal; 
end;
/

答案 1 :(得分:0)

这不是编译器输出,它是SQL * Plus输出:

Enter a valeur for v_name : dhia
old 6 : v_name:=&v_name;
new 6 : v_name:=dhia;

&v_namesubstitution variable(也称为定义变量),这意味着SQL * Plus会在将文本文本&v_name发送到文字dhia之前盲目地替换new 6。用于编译和执行的数据库。上面的v_name := dhia;行显示了此文本替换后代码的外观。如您所见,dhia仅在名为v_name := '&v_name'; 的范围内有另一个变量或函数时才有效。如果要对文本值使用替换变量,则需要引用它:

dbms_output

这也意味着你的EMP5命令直到替换后才会被执行,这使得它们有些无用。如果要捕获用户的输入,请在PL / SQL块启动之前使用accept命令。

您的示例中的另一个问题是,如果insert表不存在,则由于execute immediate命令中对不存在的表的引用,该块将无法编译;但如果确实存在,则execute immediate将失败。您需要在单独的步骤中创建表,或者使用 weights<-c(1/3,1/3,1/3) means<-matrix(1:6,nrow=3,byrow=FALSE) covars<-array(1,dim=c(2,2,3)) EM(d,weights,means,covars,300,3,10,0.0001) 来对其进行所有引用,并处理已存在的情况。