2012-03-24 27 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

最好的問候,並希望我是有幫助的

相關問題