2

我是 PL/SQL 的新手,所以如果这看起来太像初学者的问题,请不要标记我。我已经花了几个小时来解决这个问题,现在正在寻求帮助。此外,请记住此代码不完整。我正在寻求帮助来完成它。所以我正在尝试为我的测试表创建一个名为 KEYBOARD_LEARNING 的简单过程。我以前必须手动使用此代码:

INSERT INTO keyboard_learning (emplid, wpm, date_completed,exercise,attempt,score_lvl) 
VALUES ('000000000','37.66','04-JUL-2012','Keyhero.com','28','95.87% accuracy')

..每次我想在 KEYBOARD_LEARNING 中记录一个新分数。我想我可以创建一个程序来为我处理这个问题,但我需要它不是静态的,因为我在调用这个程序时输入的值总是在变化。关于如何使我拥有的代码具有这种最佳功能的任何想法?顺便说一句,下面的代码没有执行,我相信有经验的 Oracle 用户将能够立即找出原因。

谢谢

CREATE OR REPLACE PROCEDURE INSERT_WPM_SCORE
(
          P_EMPLID VARCHAR2
         ,P_WPM NUMBER
         ,P_DATE_COMPLETED SYSDATE
         ,P_EXERCISE VARCHAR2
         ,P_ATTEMPT VARCHAR2
         ,P_SCORE_LVL VARCHAR2
) AS

          /*
          Original Author: 
          Created Date: 2-Aug-2012
          Purpose: For inputting latest WPM score from typing practice
          */

          /*variables*/

          L_EMPLID VARCHAR2(4000);
          L_WPM NUMBER;
          L_DATE_COMPLETED SYSDATE;
          L_EXERCISE VARCHAR2(4000);
          L_ATTEMPT VARCHAR2(4000);
          L_SCORE_LVL VARCHAR2(4000);
          L_PREVENT_NULL_INPUT EXCEPTION;
          PRAGMA EXCEPTION_INIT(L_PREVENT_NULL_INPUT, -44002); --GET CORRECT ERROR # BY TESTING WITHOUT EXCEPTION
          VALUES VARCHAR2(4000);  [b]<-- getting an error here[/b]

          /*Procedure 'W' is a wrapper for DBMS output*/
          PROCEDURE W(STR VARCHAR2) IS
                        L_STRING VARCHAR2(4000);
          BEGIN
                        /*Outputting string parameter passed into 'W' procedure*/
                        L_STRING := STR;
                        DBMS_OUTPUT.PUT_LINE(STR);
          END;

BEGIN

         VALUES := (L_EMPLID, L_WPM,  L_DATE_COMPLETED, L_EXERCISE,  L_ATTEMPT,L_SCORE_LVL);

          SELECT INTO (SELECT *
                       FROM KEYBOARD_LEARNING A
                       ORDER BY A.EXERCISE
                               ,TO_NUMBER(ATTEMPT))

                     -- DBMS_OUTPUT.PUT_LINE(RESULTS);

EXCEPTION
          /* */            
          WHEN L_PREVENT_NULL_INPUT THEN
                        NULL;

          /*this exception catches all other exceptions*/
          WHEN OTHERS THEN
                        W('ERROR: ' || SQLERRM);

END;
4

1 回答 1

4

首先,让我们实现最简单的可行的方法

CREATE OR REPLACE PROCEDURE INSERT_WPM_SCORE
(
          P_EMPLID VARCHAR2
         ,P_WPM NUMBER
         ,P_DATE_COMPLETED DATE DEFAULT SYSDATE
         ,P_EXERCISE VARCHAR2
         ,P_ATTEMPT VARCHAR2
         ,P_SCORE_LVL VARCHAR2
) AS
BEGIN
  INSERT INTO keyboard_learning (emplid, wpm, date_completed,exercise,attempt,score_lvl) 
    VALUES( p_emplid, p_wpm, p_date_completed, p_exercise, p_attempt, p_score_lvl );
END;

假设这可行,那么您可以向该过程添加额外的功能。不幸的是,对我来说,您想要实现哪些附加功能并不明显。

  • 例如,您有一个似乎想要根据NULL输入抛出和/或捕获的异常,但我不确定它试图完成什么。您是否尝试验证程序的输入?您是否试图捕获在执行INSERT并违反NOT NULL约束时引发的异常?还有什么?
  • 我不确定SELECT您原始帖子中的声明是什么意思。也许您正试图覆盖p_attempt传递给过程的那个?

此外,作为一般规则,捕获您无法处理的异常是一个错误,WHEN OTHERS而后面没有 a 的 aRAISE几乎总是一个错误。如果您捕获异常并将其写入SQLERRMDBMS_OUTPUT您将丢失异常提供的所有有用的堆栈跟踪信息,您将丢失生成错误的代码的行号,您依赖于客户端应用程序来实际启用DBMS_OUTPUT缓冲区并从中读取(大多数客户端应用程序没有),并且您正在阻止过程的调用者确定调用失败。完全消除异常处理程序会更好地为您服务。

于 2012-08-07T22:20:37.200 回答