我有一个表,该表的数据类型为LONG。如果编写基本查询以获取该LONG colmun的值,则将得到正确的结果。 例如:
select long_text from fnd_documents_long_text;
这将返回正确的值。
但是,如果我尝试在LONG列中使用case语句,则会出现ORA-00997:非法使用LONG数据类型错误。 我正在尝试编写以下查询:
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列的值。
我真正想要的是,如果datatype_id = 1,则从fnd_documents_short_text表中获取short_text,否则,如果datatype_id为2,则从fnd_documents_long_text表中获取long_text,其中“ long_text”的数据类型为LONG。这些是标准的Oracle APPs表。我正在按照以下方式编写查询。.但无法正常工作:
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 ;
谢谢, 阿卜哈
答案 0 :(得分:2)
restrictions on the LONG
data type有很多,这会限制您的选择。
作为您方案的一种可能的解决方法,您可以创建一个函数,将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的一部分,因此您不需要永久数据库对象(尽管您可能经常这样做可能会这样做):
-- 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;
答案 1 :(得分:1)
按照建议的here,您可以使用全局临时表
首先将表的相关部分(记录)插入临时表中。比您可以根据需要从中进行选择,因为临时表中的两列都具有相同的类型-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
答案 2 :(得分:0)
为什么不只做Join?
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;
如果要使用案例/联合查询,可以执行以下操作:
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 ;