2013-04-27 76 views
0

我是一般的PL/SQL和存储过程的新手。我正在尝试编写一个将通过CallableStatement从Java程序执行的存储过程。该过程需要两个参数,获取最后一个记录的id,将其增加并插入一个新记录,并添加新增的id。我在网上发现了一些基本上做同样事情的例子,但我无法解决这些错误。INSERT存储过程(PL/SQL)

CREATE OR REPLACE PROCEDURE insertEmployeeProcedure 
(lastname IN VARCHAR, firstname IN VARCHAR) AS 
BEGIN 
    lastEmpId NUMBER := SELECT COUNT(*) 
    INTO lastEmpId 
    FROM Employees; 

    INSERT INTO Employees(id, lname, fname) VALUES(lastEmpId + 1, lastname, firstname); 
END insertEmployeeProcedure; 
/

的错误是:

Executed successfully in 0.018 s, 0 rows affected. 
Line 1, column 1 
Error code 984, SQL state 42000: ORA-00984: column not allowed here 
Line 8, column 5 
Error code 900, SQL state 42000: ORA-00900: invalid SQL statement 
Line 9, column 1 
Error code 0, SQL state null: java.lang.NullPointerException 
Line 9, column 1 
Execution finished after 0.018 s, 3 error(s) occurred. 

据我明白一个存储过程是PL的混合和SQL.That说,我试图递增lastEmpId(如lastEmpId:= lastEmpId + 1)但得到了“无效的SQL语句”错误。 另外,Oracle docs(http://docs.oracle.com/cd/B28359_01/appdev.111/b28843/tdddg_procedures.htm#CIHBCBHC)在解释如何定义和使用存储过程中的局部变量方面做得并不好。

在此先感谢。

+0

即使忽略了一个事实,你是这里不使用序列 - 执行'select max(id)from ...'而不是count(*)'会更好,因为oracle可以使用最小/最大扫描并获得最多只有两个(或三个)来自索引的CR。 – haki 2013-04-28 08:34:42

+0

varchar2是更常见的数据类型 - Oracle不鼓励使用varchar。另外,对象名称在Oracle中不区分大小写,除非使用双引号(大多数从业者不会),而“procedure”一词是多余的,因此该过程的更常规名称为insert_employee。 – 2013-04-28 17:53:15

回答

3

你可能要像

CREATE OR REPLACE PROCEDURE insertEmployeeProcedure 
(lastname IN VARCHAR, firstname IN VARCHAR) AS 

    lastEmpId NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO lastEmpId 
    FROM Employees; 

    INSERT INTO Employees(id, lname, fname) VALUES(lastEmpId + 1, lastname, firstname); 
END insertEmployeeProcedure; 
/

注意,变量之前声明BEGIN部分。

另外,如果你使用SQL开发人员,你执行包创建的代码运行

show errors 

后,它会告诉你任何问题,你真正调用程序之前。

+0

移动声明块中的变量。谢谢。在INSERT行仍然出现“列不允许在这里”。看起来像适合我的SQL。 – Dmitry 2013-04-27 19:20:07

+0

我只是试了一下,它工作正常。你有更多的细节吗? – 2013-04-27 19:27:25

+0

我已连接到数据库并从NetBeans IDE运行命令。将尝试SQL开发。 – Dmitry 2013-04-27 19:34:22

2

您必须使用序列来增加id列。并不总是行数相匹配上次使用的ID

一个例子创建序列:

CREATE SEQUENCE sequence_name 
MINVALUE 1 
START WITH 1 
INCREMENT BY 1 
CACHE 20; 

如何使用这个序列的一个例子如下:

CREATE OR REPLACE PROCEDURE insertEmployeeProcedure 
(lastname IN VARCHAR, firstname IN VARCHAR) AS 
BEGIN 
    INSERT INTO Employees(id, lname, fname) VALUES(sequence_name.nextval, lastname, firstname); 
END insertEmployeeProcedure; 
+0

试过这个。大多数错误都没有了!由于某种奇怪的原因,最后一行仍然是“无效的SQL”。谢谢。 – Dmitry 2013-04-27 19:32:30

相关问题