2012-03-24 42 views
0

下面是我的代码给出如下。我试图添加5个参数,该函数将这些参数放入Employee表中。但我没有成功,做了很多事情。Oracle中的存储函数无法将值插入所需的表

错误

ORA-01858: a non-numeric character was found where a numeric was expected ORA-06512: at "xxxxxxx.A1SF_ADDEMP", line 14 01858. 00000 - "a non-numeric character was found where a numeric was expected" *Cause: The input data to be converted using a date format model was incorrect. The input data did not contain a number where a number was required by the format model. *Action: Fix the input data or the date format model to make sure the elements match in number and type. Then retry the operation.

加上我怎么测试存储功能具有插入/更新或删除它的声明?

执行语句

Select A1SF_ADDEMP('Adesh', '33', 'M', 8000, '26/03/1990') 
From dual; 

代码

CREATE OR REPLACE Function A1SF_ADDEMP 
     (pEmpName In Varchar2, 
     pTaxFileNo In Varchar2, 
     pGender In Varchar2, 
     pSalary In Number, 
     pBirthdate In Varchar2 
     ) Return Varchar2 
     Is 
      tEmpId Number(38,0); 
      tBirthDate Date; 

     BEGIN 
       tEmpId := A1Seq_Emp.nextval; 
       tBirthdate := to_date('pBirthdate','dd/mm/yyyy'); 

       Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate) 
       Values (tEmpId, pEmpName, pTaxFileNo, pGender, pSalary, tBirthdate);     
       Commit; 
       Return null; 
     END; 

回答

1

首先,你不能把在它DML一个函数在SELECT语句。你必须分配输出到一个PL/SQL块的变量,像这样:

declare 
    l_output number; 
begin 
    l_output := my_function(variable1, variable2); 
end; 

这是不好的做法,做DML的功能;部分原因是它会导致你遇到的错误。您应该使用下面详述的过程。另一个原因是你总是返回空值,根本不需要返回任何东西!

create or replace procedure my_procedure (<variables>) is 
begin 

    insert into employees(<columns>) 
    values (<values >); 

end; 

的具体原因你的错误是这样的一行:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');

pBirthdate已经是一个字符串;通过在其周围放置一个',您将字符串'pBirthdate'传递给函数to_date,并且Oracle无法将此字符串转换为日,月或年,因此失败。

你应该写为:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');

你也不需要指定number(38,0),你可以只写number代替。

可以使用out关键字从过程中返回值。如果我们假设你想返回empid你可以写是这样的:

create or replace procedure A1SF_ADDEMP (
      pEmpName in varchar2 
     , pTaxFileNo in varchar2 
     , pGender in varchar2 
     , pSalary in number 
     , pBirthdate in varchar2 
     , pEmpid out number 
     ) return varchar2 is 

begin 

    pempid := A1Seq_Emp.nextval; 

    Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate) 
    Values (pEmpId, pEmpName, pTaxFileNo, pGender 
      , pSalary, to_date(pBirthdate,'dd/mm/yyyy');  

end; 

要只是执行过程中调用它像这样:

begin 

    A1SF_ADDEMP(EmpName, TaxFileNo, Gender 
       , Salary, Birthdate); 
    commit; 

end; 

如果你想要回empid然后你可以这样调用:

declare 

    l_empid number; 

begin 

    l_empid := A1SF_ADDEMP(EmpName, TaxFileNo, Gender 
         , Salary, Birthdate); 
    commit; 
end; 

注意我是如何移动的commit来的最高水平,这是为了避免犯ST在每一个程序中,当你可能有更多的事情需要做时。

顺便说一下,如果您使用的是Oracle 11g,则无需将值A1Seq_Emp.nextval赋值给变量。您可以直接将其插入values列表中的表格中。您当然无法将其退回,但只要没有其他值从序列中获取值,您就可以返回A1Seq_Emp.curval

+0

我将如何执行上述功能牢记DML语句是否必须使用游标或其他? – 2012-03-24 13:26:29

+0

@ extinguisher33,正如我在我的回答中解释的那样,你必须将它包装在PL/SQL块中;但我会将它转化为一个程序。 – Ben 2012-03-24 13:27:40

+0

程序事情我知道的原因我已经学习了SQL Server,但我非常感兴趣知道如何调用,在Sql开发人员上测试此函数,以及如何从Visual Studio调用它) – 2012-03-24 13:29:30

1

,如果你不返回任何值,你应该使用程序(而不是函数)。

如果你看一下在错误消息中提到,你可以发现你的错误的行:

tBirthdate := to_date('pBirthdate','dd/mm/yyyy'); 

您传递字符串文字“pBirthdate”到TO_DATE()调用。但你想通过参数,所以它应该是

tBirthdate := to_date(pBirthdate,'dd/mm/yyyy'); 

(注意丢失的单引号arount pBirthdate)。

因此,作为一个过程,整个事情是这样的:

CREATE OR REPLACE PROCEDURE A1SF_ADDEMP 
     (pEmpName In Varchar2, 
     pTaxFileNo In Varchar2, 
     pGender In Varchar2, 
     pSalary In Number, 
     pBirthdate In Varchar2 
     ) 
IS 
BEGIN 
    Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate) 
    Values (A1Seq_Emp.nextval, pEmpName, pTaxFileNo, pGender, pSalary, to_date(pBirthdate,'dd/mm/yyyy')); 
    Commit; 

END; 

运行它

execute A1SF_ADDEMP('Adesh', '33', 'M', 8000, '26/03/1990'); 
+0

不能这样执行它。错误报告: ORA-06550:第1行第7列: 错误报告: 执行A1SF_ADDEMP('Adesh','33','M',8000,'26/03/1990' PLS-00221:'A1SF_ADDEMP'不是程序或未定义 ORA-06550:第1行第7列: PL/SQL:语句被忽略 06550. 00000 - “行%s,列%s:\ n%s “ *原因:通常是PL/SQL编译错误。 *操作: – 2012-03-24 13:16:27

+0

何时发生此错误?当你运行CREATE语句或者当你运行EXECUTE语句时?如果它是执行语句,那么你是否在运行CREATE之前创建一个过程而不是函数? – 2012-03-24 13:21:47

+0

只有程序可以像这样执行。 – 2012-03-24 13:22:58

0

在您的情况下,您需要使用带out参数的过程,其中out参数是您的返回参数,其中包含您期望的值。这是我想在这种情况下,当你想在select语句中使用DML的最佳实践。

第二种方式做到这一点,但它不是一个好的做法是使用一个像你的函数,但在返回值之前,你需要使用if语句来检查什么是值,如果值是你想要调用的值如果声明PRAGMA AUTONOMOUS_TRANSACTION过程,它将独立于调用它的函数执行你的DML。有关编译事务的详细信息您可以在这里阅读: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm

最好的问候,并希望我是有帮助的

相关问题