背景:ALL_IND_EXPRESSIONS
有列
COLUMN_EXPRESSION LONG Function-based index expression defining the column
我知道LONG
已被弃用。我需要写一些像(或做其他文本操作)的东西:
SELECT
REPLACE(REPLACE(REPLACE(
q'{ALTER INDEX "<index_owner>"."<index_name>" ON ... (<column_expression>)}'
,'<index_owner>', index_owner )
,'<index_name>', index_name)
,'<column_expression>', column_expression) AS result
FROM all_ind_expressions;
ORA-00932:不一致的数据类型:预期NUMBER变长
说明:
PL/SQL block
DBMS_METADATA.GET_DDL
(事实并非如此)是否可以从LONG
转换/转换/使用内置函数到VARCHAR2
?
EDIT TL; DR:
SELECT column_expression || 'a' -- convert to working code
FROM all_ind_expressions;
答案 0 :(得分:6)
除非表达式包含可以强制解析XML的内容,否则可以使用XML。
select *
from xmltable(
'/ROWSET/ROW'
passing (select dbms_xmlgen.getxmltype('select * from all_ind_expressions
where index_name = ''XDB$COMPLEX_TYPE_AK''')
from dual)
columns index_owner varchar2(30) path 'INDEX_OWNER',
index_name varchar2(30) path 'INDEX_NAME',
table_owner varchar2(30) path 'TABLE_OWNER',
table_name varchar2(30) path 'TABLE_NAME',
column_expression varchar2(4000) path 'COLUMN_EXPRESSION')
INDEX_OWNER INDEX_NAME TABLE_OWNER TABLE_NAME COLUMN_EXPRESSION
--------------- -------------------- --------------- -------------------- -----------------------------------
XDB XDB$COMPLEX_TYPE_AK XDB XDB$COMPLEX_TYPE SYS_OP_R2O("XMLDATA"."ALL_KID")
1 row selected.
答案 1 :(得分:2)
使用WITH FUNCTION
并从Converting Long to Varchar2接近,但它仍然有些丑陋且过于复杂。
CREATE TABLE TEST(Z INT);
CREATE INDEX IF_DOUBLE_TEST_Z ON TEST(Z*2);
查询:
WITH FUNCTION s_convert(pindex_owner VARCHAR2, pindex_name VARCHAR2,
ptable_owner VARCHAR2, ptable_name VARCHAR2)
RETURN VARCHAR2
AS
VAR1 LONG;
VAR2 VARCHAR2(4000);
BEGIN
SELECT column_expression
INTO VAR1
FROM all_ind_expressions
WHERE index_owner = pindex_owner AND index_name = pindex_name
AND table_owner = ptable_owner AND table_name = ptable_name
AND column_position = 1; -- only one column indexes
VAR2 := SUBSTR(VAR1, 1, 4000);
RETURN VAR2;
END;
SELECT aie.*,
REPLACE(REPLACE(REPLACE(
q'{ALTER INDEX "<index_owner>"."<index_name>" ON ... (<column_expression>)}'
,'<index_owner>', index_owner )
,'<index_name>', index_name)
,'<column_expression>',
s_convert(index_owner, index_name, table_owner, table_name)) AS result
FROM all_ind_expressions aie
WHERE TABLE_NAME='TEST';
<强> db<>fiddle demo 强>
我相信应该有更优雅的方式来实现它。
答案 2 :(得分:2)
正如oracle专家自己所说,由于遗留原因,不可能将SUBSTR内容延长到VARCHAR2。 AskTom link
在此other link上,如果LONG短于32k LONG,您将找到使用程序执行此操作的方法,甚至可以使用函数。
稍后可以在SELECT查询中调用此函数,这是您可能想要实现的。
答案 3 :(得分:0)
处理长时的最佳方法是: 1)创建一个具有lob类型的临时表(例如CLOB)。 2)使用oracle唯一允许的语法: “ TO_LOB将long_column列中的LONG或LONG RAW值转换为LOB值。您只能将此功能应用于LONG或LONG RAW列,并且只能在INSERT语句的子查询的选择列表中应用。 3)利用临时表来做您的事情