Oracle SQL错误代码ORA-06502:PL/SQL:数字或值错误:第18行的字符串缓冲区太小

Oracle SQL错误代码ORA-06502:PL/SQL:数字或值错误:第18行的字符串缓冲区太小,sql,oracle,Sql,Oracle,我一直在努力修复这个错误一段时间,但我无法解决它。我已经研究了这个错误代码,问题是我试图存储一个无法放入变量的数字/字符。在我的代码中,一切看起来都很好,我找不到问题 以下是学员表信息: COLUMN_NAME DATA_TYPE NULLABLE DATA_DEFAULT COLUMN_ID COMMENTS 1 STU_ID NUMBER(6,0) Yes (null) 1 (null) 2 LAME CH

我一直在努力修复这个错误一段时间,但我无法解决它。我已经研究了这个错误代码,问题是我试图存储一个无法放入变量的数字/字符。在我的代码中,一切看起来都很好,我找不到问题

以下是学员表信息:

  COLUMN_NAME DATA_TYPE      NULLABLE DATA_DEFAULT COLUMN_ID COMMENTS 
1 STU_ID      NUMBER(6,0)    Yes      (null)       1         (null) 
2 LAME        CHAR(8 BYTE)   Yes      (null)       2         (null) 
3 FAME        CHAR(8 BYTE)   Yes      (null)       3         (null)
4 MI          CHAR(2 BYTE)   Yes      (null)       4         (null) 
5 SEX         CHAR(2 BYTE)   Yes      (null)       5         (null) 
6 MAJOR       CHAR(10 BYTE)  Yes      (null)       6         (null) 
7 HOME_STATE  CHAR(5 BYTE)   Yes      (null)       7         (null)
以下是我正在使用的代码:

SET SERVEROUTPUT ON;
DECLARE
  class_num NUMBER(6) := 0;
  counter NUMBER := 0;
  total NUMBER := 0;
  state CHAR(5);
  in_state NUMBER := 0;
  out_state NUMBER := 0;
  Stu_name CHAR;
BEGIN
  SELECT COUNT(Home_State) INTO total FROM Student;
  FOR counter IN 1..(total)
   LOOP
    class_num := 10010 + counter;
    SELECT Home_State
     INTO state
      FROM Student
       WHERE Stu_ID = class_num;
    SELECT Fname
     INTO Stu_name
      FROM Student
       WHERE Stu_ID = class_num;
    IF state = 'Tx'
     THEN
      DBMS_OUTPUT.PUT_LINE(Stu_name||'is in state.');
      in_state := in_state + 1;
    ELSE
      DBMS_OUTPUT.PUT_LINE(Stu_name||'is out of state');
      out_state := out_state + 1;
    END IF;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('There are '||in_state||' students in state.');
  DBMS_OUTPUT.PUT_LINE('There are '||out_state||' students out of state.');
END;
运行代码时,我收到以下错误消息:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 18
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.

我想知道这个学生是在德克萨斯州还是在德克萨斯州。我将根据学生是否在德克萨斯州境内或境外,在州内或州外添加1。我还将打印一条消息,告诉用户该学生在德克萨斯州境内或境外。循环完成后,我将打印“处于”状态和“处于”状态的总数。

我认为您关于错误位置的看法是错误的。应该是下一个命令:

 SELECT Fname
     INTO Stu_name
因为您声明了STU_NAME CHAR;这还不够

您更希望声明变量,以便它们继承列的数据类型,例如

declare
  stu_name student.fname%type;
这样做,您将避免此类问题


此外,除非存储在此类列/变量中的值是固定长度的,否则请尽量避免使用CHAR数据类型。因为-CHAR right将空格填充到列的最大长度,所以通常必须截断它。改为选择VARCHAR2。

正确。Tom Kyte强烈建议不要使用CHAR,谢谢你的帮助。我修正了我的代码,现在可以用了。我将仔细检查并将所有的CHAR类型更改为VARCHAR2类型。此外,您还希望将数据类型大小定义为CHAR,而不是BYTE。如果您的数据中有任何多字节字符,那么这些字符将不仅仅是一个字节,而只是一个字符,这使得调试非常困难。