0

我正在尝试使用 SQLLoader 将一些数据加载到 Oracle 数据库,但我不断收到错误ORA-00932: inconsistent datatypes: expected DATE got NUMBERexpecting char got date

日期以 eg 的格式出现20130815,它将被存储到具有 type 列的数据库中Date

逻辑应该是,如果有人null在日期字符串中传递了一个无效的日期 a 或说一个无效的月份20131301,那么我想插入一个默认日期,例如19990101

这是我到目前为止的 SQLLoader 代码:

COLUMN_DOB   DATE 'YYYYMMDD' "CASE:COLUMN_DOB WHEN 'isdate(:COLUMN_DOB)=1' THEN :COLUMN_DOB ELSE to_date('19000101', 'YYYYMMDD') END",,
4

1 回答 1

1

直接的问题是您正在调用to_date()固定值。该then部分正在从文件中返回日期的原始字符串值;正在else返回一个date;这导致“期望字符得到日期”消息。

如果您删除该to_date()部分,那么它会将所有值加载为 1900-01-01,因为您的 case 语句错误。您正在将:COLUMN_DOBvalue 与 string进行比较'isdate(:COLUMN_DOB)=1'。它没有调用该函数,它是一个固定字符串,并且您的日期字段永远不会与该文本完全匹配。所以case总是进入else并获得固定值。您似乎也混淆了两种形式的case陈述。

所以应该是:

... "CASE WHEN isdate(:COLUMN_DOB)=1 THEN :COLUMN_DOB ELSE '19000101' END"

其中,假设您已经构建了一个isdate()函数 - 因为它不是 Oracle 内置的 - 具有默认格式掩码,类似于基于 AskTom 版本的函数

create or replace function isdate (p_string in varchar2,
  p_fmt in varchar2 := 'YYYYMMDD')
return number as
  l_date date;
begin
  if l_date is null then
    return 0;
  end if;
  l_date := to_date(p_string, p_fmt);
  return 1;
exception
  when others then
     return 0;
end;
/

... 将输入提供的有效日期,无效日期为 1900-01-01。空值检查也意味着空值将作为 1900-01-01 插入;在这里拥有它可能比尝试在控制文件中单独处理它更简单。

您可以通过使用一个尝试转换字符串并返回日期的函数来进一步简化它,然后在控制文件中调用它,而不使用date掩码或case语句。该方法也包含在 AskTom 链接中。

就个人而言,我可能更愿意看到该列留空,而不是给它一个幻数。拥有有效 DOB 为 1900-01-01 的人并非不可能。


如果您仍然要创建一个新函数,您可以这样做:

create or replace function my2date(p_str in varchar2) return date is
begin
  return to_date(nvl(p_str, '19000101'), 'YYYYMMDD');
exception
  when others then -- just about acceptable here
    return date '1900-01-01';
end;
/

您可以从 SQL*Plus、SQL Developer、Toad 或您使用的任何客户端执行。然后您的控制文件将具有:

COLUMN_DOB "my2date(:COLUMN_DOB)"

我认为不使用函数就没有办法做到这一点。如果您改用外部表,那么您可以使用匿名块来进行我想的转换,但是如果您坚持使用 SQL*Loader,那么我相信函数是停止导致整行的错误日期的唯一方法被拒绝。

于 2013-08-15T14:33:29.707 回答