我编写了一个管道函数来从远程数据库查询数据。我不断得到
ORA-06502: PL/SQL: 数字或值错误: 字符串缓冲区太多 小。
我想我确实理解何时会发生此错误,例如当表列定义为
VARCHAR2(10)
并且您尝试插入大于 10 字节的内容时。但在这种情况下,我真的看不出有什么问题。
也许首先我会显示本地和远程数据库的参数。我认为这可能很重要,在两个数据库上
NLS_LENGTH_SEMANTICS
设置为 BYTE
。
现在本地数据库中的代码:
create or replace function f_get_pl_data return tb_pl_palette pipelined is
begin
for i in (select p.*, 123 LAGER from palette@myremotedb p)
loop
pipe row(tt_pl_palette(i.pid,i.bereich,i.regal,i.fach,i.ebene,i.vol_klasse,i.lhm_typ,i.zustand,i.neu_datum,
i.neu_zeit,i.neu_usr,i.aender_datum,i.aender_zeit,i.aender_usr,i.verl_datum,i.tournr,
i.fil_nr,i.retournr,i.fz_nr,i.fahrer_nr,i.eroeff_auswahl,i.tpa_knz,i.lfsaender_knz,
i.verladen_am,i.verladen_um,i.verladen_von,i.verladen_von2,i.leer_gew,i.soll_gew,
i.ist_gew,i.lager));
end loop;
return;
end;
CREATE OR REPLACE TYPE "TT_PL_PALETTE" AS OBJECT (
pid VARCHAR2(14),
bereich VARCHAR2(2),
regal VARCHAR2(2),
fach VARCHAR2(3),
ebene VARCHAR2(2),
vol_klasse INTEGER,
lhm_typ INTEGER,
zustand INTEGER,
neu_datum DATE,
neu_zeit VARCHAR2(11),
neu_usr VARCHAR2(4),
aender_datum DATE,
aender_zeit VARCHAR2(11),
aender_usr VARCHAR2(4),
verl_datum DATE,
tournr VARCHAR2(6),
fil_nr VARCHAR2(4),
retournr VARCHAR2(10),
fz_nr INTEGER,
fahrer_nr INTEGER,
eroeff_auswahl INTEGER,
tpa_knz VARCHAR2(1),
lfsaender_knz VARCHAR2(1),
verladen_am DATE,
verladen_um VARCHAR2(11),
verladen_von VARCHAR2(4),
verladen_von2 VARCHAR2(4),
leer_gew NUMBER(7,3),
soll_gew NUMBER(7,3),
ist_gew NUMBER(7,3),
lager NUMBER
)
CREATE OR REPLACE TYPE "TB_PL_PALETTE" as TABLE OF TT_PL_PALETTE
这是远程数据库上的表规范:
create table PALETTE
(
pid VARCHAR2(14) not null,
bereich VARCHAR2(2) not null,
regal VARCHAR2(2) not null,
fach VARCHAR2(3) not null,
ebene VARCHAR2(2) not null,
vol_klasse INTEGER,
lhm_typ INTEGER,
zustand INTEGER,
neu_datum DATE default trunc(sysdate),
neu_zeit VARCHAR2(11) default to_char(sysdate, 'HH24:MI:SS'),
neu_usr VARCHAR2(4),
aender_datum DATE,
aender_zeit VARCHAR2(11),
aender_usr VARCHAR2(4),
verl_datum DATE,
tournr VARCHAR2(6),
fil_nr VARCHAR2(4),
retournr VARCHAR2(10),
fz_nr INTEGER,
fahrer_nr INTEGER,
eroeff_auswahl INTEGER,
tpa_knz VARCHAR2(1) default '0',
lfsaender_knz VARCHAR2(1) default 'N',
verladen_am DATE,
verladen_um VARCHAR2(11),
verladen_von VARCHAR2(4),
verladen_von2 VARCHAR2(4),
leer_gew NUMBER(7,3),
soll_gew NUMBER(7,3),
ist_gew NUMBER(7,3)
)
所以你可以看到,当我在本地数据库中创建类型时,我选择了远程数据库中列的确切大小。 但是当我执行/查询管道函数时,我收到此错误(抱歉,这是德语,但我在标题中写了英语):
怎么会发生这种事?你知道出了什么问题吗? 感谢任何帮助,谢谢!
编辑2021-03-02: @ShaunPeterson感谢您的回复,NLS_CHARACTERSET 在本地和远程数据库上都设置为 AL32UTF8。
我刚刚发现,问题似乎是由我们公司使用的2个不同的IDE引起的。 我正在使用全自动化的 PL/SQL Developer。当我在远程数据库(表“PALETTE”)上发布表规范时,我使用该 IDE 连接到远程数据库,它显示了列类型/大小,正如您在我的原始帖子中看到的那样。我重复前 6 列:
create table PALETTE
(
pid VARCHAR2(14) not null,
bereich VARCHAR2(2) not null,
regal VARCHAR2(2) not null,
fach VARCHAR2(3) not null,
ebene VARCHAR2(2) not null,
vol_klasse INTEGER,
但是当使用 Oracle SQL Developer 时,则看起来像这样:
CREATE TABLE "PSTEDI"."PALETTE"
( "PID" VARCHAR2(14 CHAR) NOT NULL ENABLE,
"BEREICH" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"REGAL" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"FACH" VARCHAR2(3 CHAR) NOT NULL ENABLE,
"EBENE" VARCHAR2(2 CHAR) NOT NULL ENABLE,
"VOL_KLASSE" NUMBER(*,0),
所以看来 PL/SQL Developer 只是显示了错误的规范。我不知道为什么会这样,我很想知道,但那是另一个问题了。 我使用 Oracle SQL Developer 显示的列类型和大小解决了我的问题。
谢谢你。
@Dietz,你说的对我来说很好。
我也遇到了和你一样的问题,不知道是不是bug。喜欢你:
但是:
仅供参考,我将再尝试一件事,如果不起作用,我将向 Oracle 支持开具一张票证。我将在此处更新我在 Oracle 支持中找到的内容或解决方法。
我相信这不是一个错误,而是你的 IDE 的一个功能。 SQL-Developer 为您的数据库会话提供了一个预设,用于设置您的 NLS 环境:
“Database/NLS”下的预设允许(除其他外)特定于会话的 LENGTH 语义设置(此屏幕截图中的“Länge”)。
Oracle DB 允许不同级别的 NLS 设置,并可通过以下视图进行访问: NLS_DATABASE_PARAMETERS、NLS_INSTANCE_PARAMETERS、NLS_SESSION_PARAMETERS。 使用
ALTER SESSION SET [NLS_parameter_name] = <desired value>;
例如
ALTER SESSION SET NLS_LENGTH_SEMANTICS = 'BYTE';
手动更改您的会话设置。
因此,PLSQL-Developer 在创建表时可能使用长度设置“CHAR”作为默认会话设置,而 Oracle SQL Developer 确实使用“BYTE”——并且由于不是默认值而显示了显式“CHAR”语义。