it-swarm.com.de

Wie man LONG in VARCHAR2 inline umsetzt

Hintergrund: ALL_IND_EXPRESSIONS hat Spalte

COLUMN_EXPRESSION   LONG   Function-based index expression defining the column

Ich weiß, dass LONG veraltet ist. Ich muss etwas schreiben (oder andere Textoperationen ausführen):

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: inkonsistente Datentypen: erwartete NUMBER hat LANGE

DBFiddle Demo

Bemerkungen:

  • es muss sich um eine eigenständige Abfrage handeln
  • keine Zwischenobjekte (das Erstellen einer Tabelle/Ansicht ist keine Option).
  • nein PL/SQL block
  • DBMS_METADATA.GET_DDL (das ist nicht der Fall)
  • WITH FUNCTION-Klausel als letzter Ausweg

Kann ich die eingebaute Funktion von LONG in VARCHAR2 umwandeln/konvertieren/verwenden?

TL BEARBEITEN; DR:

SELECT column_expression || 'a'  -- convert to working code
FROM all_ind_expressions;
8
Lukasz Szozda

Sie können XML verwenden, es sei denn, Ausdrücke enthalten etwas, das die XML-Analyse bremsen kann.

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.
6
Dr Y Wit

Wie Oracle-Experten selbst festgestellt haben, ist es aus alten Gründen nicht möglich, SUBSTR LONG in einen VARCHAR2 zu integrieren. AskTom-Link .

Auf diesem anderen Link finden Sie Möglichkeiten, dies mit einer Prozedur und sogar mit einer Funktion zu tun, wenn LONG kürzer als 32k lang ist. 

Diese Funktion kann später in einer SELECT-Abfrage aufgerufen werden, was Sie möglicherweise erreichen möchten.

2
hi olaf

Verwenden Sie WITH FUNCTION und nähern Sie sich von Convert Long in Varchar2 , aber trotzdem ist es irgendwie hässlich und überkompliziert.

CREATE TABLE TEST(Z INT);
CREATE INDEX IF_DOUBLE_TEST_Z ON TEST(Z*2);

Abfrage:

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 <> Geige-Demo

Ich glaube, dass es einen eleganteren Weg geben sollte, um dies zu erreichen.

2
Lukasz Szozda

Der beste Weg mit Long umzugehen ist: 1) Erstellen Sie eine temporäre Tabelle mit einem LOB-Typ (zB CLOB). 2) Verwenden Sie die einzig von Oracle zugelassene Syntax: "TO_LOB konvertiert LONG- oder LONG RAW-Werte in der Spalte long_column in LOB-Werte. Sie können diese Funktion nur auf eine LONG- oder LONG RAW-Spalte und nur in der Auswahlliste einer Unterabfrage in anwenden eine INSERT-Anweisung. " 3) Nutzen Sie die temporäre Tabelle für Ihre Aufgaben

0
Leon