如何在 Oracle SQL Developer 中运行过程

And*_*rej 6 oracle oracle-11g plsql

你好我在oracle SQL developer中有一个名为CITY的表,我的问题是如何运行该程序

-- start the script

SET SERVEROUTPUT ON
SET LINESIZE 400
SET TIMING ON

CREATE OR REPLACE PACKAGE BODY hotel AS

    -- -----------------------------------------------------
    -- Table city
    -- -----------------------------------------------------
    PROCEDURE fill_city(number_city NUMBER) IS
        city VARCHAR2(100);
        postna_st VARCHAR2(4);

    BEGIN
        FOR st IN 1..number_city LOOP
            city:= dbms_random.string('a',100);
            postal_number:= dbms_random.value(1000,9000);
            INSERT INTO CITY(city, postal_number) VALUES (city, postal_number);
        END LOOP;
    END;

BEGIN 
    NULL;
END hotel;
/

SHOW ERRORS;
Run Code Online (Sandbox Code Playgroud)

创建程序

CREATE OR REPLACE PACKAGE hotel AS
    PROCEDURE fill_city(number_city NUMBER)
END hotel;
/

SHOW ERRORS;
Run Code Online (Sandbox Code Playgroud)

现在如何执行程序?

--EXECUTE fill_city(10000) ;
Begin 
 fill_city(10000);
End;
Run Code Online (Sandbox Code Playgroud)

我两个都试过了,但很幸运。

我收到以下错误

 Error report:
ORA-06550: line 2, column 2:
PLS-00201: identifier 'fill_city' must be declared
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
Elapsed: 00:00:00.018
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 10

首先,如果您在包中创建过程,则在调用该过程时需要包含包名称。

begin
  hotel.fill_city(10000);
end;
/
Run Code Online (Sandbox Code Playgroud)

应该正确调用您的程序。

其次,你的局部变量的命名有问题。通常,您不会创建citypostal_number数据库中表中列的名称相同的局部变量。这使得在您打算引用局部变量的代码中引入错误变得太容易了,但范围解析规则意味着您实际上是在引用列名。例如,如果您编写完全有效的函数

CREATE OR REPLACE FUNCTION get_dname( deptno IN NUMBER )
  RETURN VARCHAR2
IS
  dname VARCHAR2(30);
BEGIN
  SELECT dname
    INTO dname
    FROM dept
   WHERE deptno = deptno;
  RETURN dname;
END;
Run Code Online (Sandbox Code Playgroud)

在您的WHERE子句中,两个对 的引用都deptno将解析为dept表中的列,而不是参数deptno。这意味着无论您向函数传递什么值,该SELECT语句都会返回表中的每一行,从而引发too_many_rows错误。通常,您会想出一个关于如何命名变量和参数的约定,这些约定不会与您的表命名约定冲突。为参数p_和局部变量添加前缀l_是一种常见的约定。这将我们的函数变成这样

CREATE OR REPLACE FUNCTION get_dname( p_deptno IN NUMBER )
  RETURN VARCHAR2
IS
  l_dname VARCHAR2(30);
BEGIN
  SELECT dname
    INTO l_dname
    FROM dept
   WHERE deptno = p_deptno;
  RETURN l_dname;
END;
Run Code Online (Sandbox Code Playgroud)

另一种选择是在引用局部变量(即get_dname.dnameget_dname.deptno)时使用显式范围前缀,而不是更改局部变量的名称。