Sql 从Oracle 11gr2中的外部表读取数据时出现无效数字错误
我有下面的DDL的外部表Sql 从Oracle 11gr2中的外部表读取数据时出现无效数字错误,sql,oracle,merge,Sql,Oracle,Merge,我有下面的DDL的外部表 CREATE TABLE emp_load ( employee_number VARCHAR2(50), employee_last_name VARCHAR2(50), employee_first_name VARCHAR2(50), employee_middle_name VARCHAR2(50), employee_hire_date VARCHAR2(50) ) organiza
CREATE TABLE emp_load
(
employee_number VARCHAR2(50),
employee_last_name VARCHAR2(50),
employee_first_name VARCHAR2(50),
employee_middle_name VARCHAR2(50),
employee_hire_date VARCHAR2(50)
)
organization external (TYPE oracle_loader DEFAULT directory abc_dir ACCESS
parameters ( records
delimited BY newline fields terminated BY '|' missing
field VALUES are NULL (employee_number, employee_last_name
, employee_first_name, employee_middle_name,
employee_hire_date) ) location ('info.dat') ) reject limit
UNLIMITED
我的.dat文件如下所示
010|ABC|DEF|XYZ|03-DEC-2011
020|CCC|123|SSS|04-DEC-2011
我有一张桌子叫
CREATE TABLE test_emp_load_1
(
mployee_number VARCHAR2(50),
employee_last_name VARCHAR2(50),
employee_first_name NUMBER(38),
employee_middle_name VARCHAR2(50),
employee_hire_date VARCHAR2(50)
)
现在我使用下面的merge语句(在下面的语句中,即使我保持e.EMPLOYEE_NUMBER='020',我认为它首先尝试对整个外部表进行扫描)
给出了下面的错误
SQL错误:ORA-29913:执行ODCIEXTTABLEFETCH调用时出错
ORA-01722:无效号码
但是当我使用
MERGE INTO test_emp_load_1 te
USING (select * from emp_load where EMPLOYEE_NUMBER = '020') e
on ( e.EMPLOYEE_FIRST_NAME = te.employee_first_name )
WHEN MATCHED THEN
UPDATE SET
te.employee_last_name = e.EMPLOYEE_LAST_NAME
WHEN NOT MATCHED THEN
INSERT
(te.employee_last_name)
VALUES
( e.EMPLOYEE_LAST_NAME)
where e.EMPLOYEE_NUMBER = '020';
我正在合并输出1行。它在Oracle11gR2中看起来是一个bug
我正在Windows平台上使用DB Oracle 11G R2。我也在Red hat Linux和Oracle 11g R2中尝试过这一点,但我也遇到了同样的问题
有什么建议吗?在您的外部表格中,您有:
employee_first_name VARCHAR2(50),
employee_first_name number(38),
on ( e.EMPLOYEE_FIRST_NAME = te.employee_first_name )
在其他表格中,您有:
employee_first_name VARCHAR2(50),
employee_first_name number(38),
on ( e.EMPLOYEE_FIRST_NAME = te.employee_first_name )
在合并中,您有:
employee_first_name VARCHAR2(50),
employee_first_name number(38),
on ( e.EMPLOYEE_FIRST_NAME = te.employee_first_name )
所以你在比较一个字符串和一个数字。它们必须作为同一类型进行比较;这两种方法都可以,但Oracle选择将字符串转换为数字来进行比较,因此它有效地做到了:
on ( to_number(e.EMPLOYEE_FIRST_NAME) = te.employee_first_name )
如果您的数据实际上是数字的,那么这是可以的,不过最好首先让数据类型正确。但您的数据不是数字,可能也不是真正的数字。再次查看示例数据:
010|ABC|DEF|XYZ|03-DEC-2011
020|CCC|123|SSS|04-DEC-2011
“first name”是文件中的第三个字段。第二行可以,因为'123'
可以转换为数字。第一行不正常,'DEF'
无法转换为数字。因此,该行被拒绝。鉴于其名称,这可能不是您最初想要的数字字段
正如Ben提到的,您的普通表中的员工编号
字段命名不正确,因此在某些时候也会出错。为了避免这些错误,您的表需要这样定义:
create table test_emp_load_1 (employee_number NUMBER,
employee_last_name VARCHAR2(50),
employee_first_name VARCHAR2(50),
employee_middle_name VARCHAR2(50),
employee_hire_date DATE)
假设所有记录实际上都有一个数字第一个字段,最后一个字段为有效日期。您的外部表定义还应该定义具有正确类型的列,并指定预期的日期格式,这样就不会出错。您应该始终使用正确的数据类型:永远不要将数字或日期存储为字符串,即使在外部表定义中也是如此(尽管它们在实际的外部文件中显然是字符串)
合并似乎也很奇怪,因为您只为插入的记录设置姓氏。那么,为什么您要将名称定义为:员工姓名号码(38)?与您的问题无关;但同样的道理;为什么您将员工编号声明为VARCHAR2(50)?还有一个MLOYEE_编号,这将是您的下一个错误…我有两个表,一个是varchar,另一个是对应于010的编号,另一个是对应于020的编号,这仍然没有真正意义,但问题出在
emoloyee_first_name
字段,不是员工编号
。再次查看示例数据。您有一行,第三个字段为DEF
,您试图在合并的on
子句中将其作为number(38)
进行比较。你得到了一个非常合理的错误,没有看到一个bug。