Sql 如何在案例选择查询中选择长列

Sql 如何在案例选择查询中选择长列,sql,oracle,Sql,Oracle,我有一个数据类型为LONG的表。如果我编写一个基本查询来获取长colmun的值,我会得到正确的结果。 例如: select long_text from fnd_documents_long_text; 这将返回正确的值 但是,如果我尝试使用带有长列的case语句,它会给出ORA-00997:非法使用长数据类型错误。 我正在尝试编写以下查询: select case when datatype_id = 2 then ( select long_text from fnd_documen

我有一个数据类型为LONG的表。如果我编写一个基本查询来获取长colmun的值,我会得到正确的结果。 例如:

select long_text from fnd_documents_long_text;
这将返回正确的值

但是,如果我尝试使用带有长列的case语句,它会给出ORA-00997:非法使用长数据类型错误。 我正在尝试编写以下查询:

 select case when datatype_id = 2 then 
 ( select long_text from fnd_documents_long_text where  media_id= fd.media_id)    end Text
 from fnd_documents fd where document_id = 715193;
您能建议我如何在Select查询中检索case语句中LONG列的值吗

我真正想要的是,如果数据类型_id=1,那么从fnd_documents_short_text table获取短文本;如果数据类型_id为2,那么从fnd_documents_long_text table获取长文本,其中“long_text”的数据类型为long。这些是标准的Oracle应用程序表。我正在写我的查询如下..但它工作不正常:

 select case when datatype_id = 1 then ( select short_text from fnd_documents_short_text where  media_id =fd.media_id)
             when datatype_id = 2 then ( select long_text from fnd_documents_long_text where  media_id =fd.media_id) 
        end Text
   from fnd_documents fd where document_id = 715193 ;
谢谢,
abha

为什么不干脆加入呢

SELECT f_d_l_t.long_text as 'Text'
FROM fnd_documents fd
INNER JOIN 
  fnd_documents_long_text f_d_l_t 
         ON f_d_l_t.media_id= fd.media_id AND fd.datatype_id=2
WHERE 
  document_id = 715193;
如果要使用case/join查询,可以执行以下操作:

SELECT 
     OTher_columns,
     MAX(CASE
         WHEN datatype_id = 1 THEN 
               f_d_s_t.short_text
         WHEN datatype_id = 2 THEN 
               f_d_l_t.long_text
     END )as 'Text'
    FROM fnd_documents fd
    LEFT JOIN 
      fnd_documents_long_text f_d_l_t 
             ON f_d_l_t.media_id= fd.media_id
    LEFT JOIN
     fnd_documents_short_text f_d_s_t 
             ON f_d_s_t.media_id= fd.media_id
    WHERE 
      document_id = 715193
    GROUP BY OTher_columns ;
按照建议,您可以使用全局临时表来解决问题

首先在临时表中插入表的相关部分(记录)。然后,您可以根据需要从中选择,因为临时表中的两列具有相同的类型-
CLOB

您不需要从临时文件中删除。表中,一个
COMMIT
就可以了

范例

create table tab
(short_text varchar2(10),
 long_text LONG,
 datatype_id number);

insert into tab values ('xxx','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 1);     
insert into tab values ('yyy','yyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 2); 
这失败了:

select datatype_id,
case when datatype_id=1 then long_text
else   short_text    end as txt from tab;

ORA-00932: inconsistent datatypes: expected LONG got CHAR
但在临时表中复制数据是可行的

CREATE GLOBAL TEMPORARY TABLE t2
(short_text CLOB,
 long_text CLOB,
 datatype_id number)
ON COMMIT DELETE ROWS;

insert into t2 (short_text,   LONG_TEXT, datatype_id )
select short_text,  to_lob(LONG_TEXT), datatype_id from tab; 

select datatype_id,
case when datatype_id=1 then long_text
else   short_text    end as txt from t2;

DATATYPE_ID TXT                                                                             
----------- --------------------------------------------------------------------------------
          1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx                                                
          2 yyy 
有很多,这限制了你的选择

作为场景的一种可能解决方法,您可以创建一个函数,将
LONG
值查询到局部变量中,然后将其作为
CLOB
返回,例如:

create or replace function get_long_text(
  p_media_id fnd_documents_long_text.media_id%type
)
return clob
as
  l_long long;
begin
  select long_text
  into l_long
  from fnd_documents_long_text
  where media_id = p_media_id;

  return to_clob(l_long);
end;
/
然后,在case表达式中,可以调用该函数:

select case
         when datatype_id = 1 then (
           select to_clob(short_text)
           from fnd_documents_short_text
           where media_id = fd.media_id
         )
         when datatype_id = 2 then get_long_text(fd.media_id) 
       end as text
from fnd_documents fd
where document_id = 715193;
或者使用左外部联接到“short”表,而不是使用子查询:

select case
         when datatype_id = 1 then to_clob(fdst.short_text)
         when datatype_id = 2 then get_long_text(fd.media_id)
        end as text
from fnd_documents fd
left join fnd_documents_short_text fdst
on fdst.media_id = fd.media_id
where fd.document_id = 715193;

在Oracle 12c中,您甚至可以将函数声明为CTE的一部分,因此不需要永久数据库对象(如果经常这样做,您可能需要):


您有一个按字面意思命名的列
LONG
?这是
LONG
列很难使用的原因之一,也是您应该使用CLOB的原因之一。。。这是您正在设计的新表,还是您一直使用的现有数据模型?@Cid否…列名不长..列名为LONG_text,数据类型为LONG。@AlexPoole:这是一个现有的EBS Oracle APPS表,我无法更改它。因此,我一直在思考如何在查询中选择列值。你知道解决这个问题的方法吗?实际上,我想使用基于数据类型\u id的case语句…如果数据类型\u id=1,那么从fnd\u文档\u short\u text table中选择数据,如果数据类型\u id=2,那么从fnd\u文档\u long\u text table中选择长文本。
-- start of CTE
with function get_long_text(
    p_media_id fnd_documents_long_text.media_id%type
  )
  return clob
  as
    l_long long;
  begin
    select long_text
    into l_long
    from fnd_documents_long_text
    where media_id = p_media_id;

    return to_clob(l_long);
  end;
-- end of CTE
select case
         when datatype_id = 1 then to_clob(fdst.short_text)
         when datatype_id = 2 then get_long_text(fd.media_id)
        end as text
from fnd_documents fd
left join fnd_documents_short_text fdst
on fdst.media_id = fd.media_id
where fd.document_id = 715193;