2017-10-28 81 views
5

Bối cảnh: ALL_IND_EXPRESSIONS có cộtLàm thế nào để đúc DÀI để VARCHAR2 inline

COLUMN_EXPRESSION LONG Function-based index expression defining the column 

Tôi biết rằng LONG bị phản đối. Tôi cần phải viết một cái gì đó tương tự (hoặc làm các hoạt động văn bản khác):

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-00.932: kiểu dữ liệu không phù hợp: SỐ dự kiến ​​có DÀI

DBFiddle Demo

Các chú thích :

  • nó phải là truy vấn độc lập
  • không có đối tượng trung gian nào (tạo bảng/chế độ xem không phải là một tùy chọn).
  • không PL/SQL block
  • DBMS_METADATA.GET_DDL (nó không phải là trường hợp)
  • WITH FUNCTION clause khu nghỉ mát như trước

Có thể đúc/chuyển đổi/sử dụng built-in chức năng LONG-VARCHAR2?

EDIT TL; DR:

SELECT column_expression || 'a' -- convert to working code 
FROM all_ind_expressions; 
+0

Bản sao có thể có của [Chuyển đổi dài sang Varchar2] (https://stackoverflow.com/questions/31004844/converting-long-to-varchar2) –

+0

@CyrilleMODIANO Câu trả lời được đề cập có thể hữu ích. 'Chuyển đổi từ dài sang varchar2 ngay lập tức bằng cách sử dụng một câu lệnh duy nhất là không thể, miễn là có một số hạn chế nhất định.'bất kỳ liên kết nào đến tài liệu chính thức? – lad2025

Trả lời

4

Bạn có thể sử dụng XML trừ khi biểu thức chứa nội dung nào đó có thể phân tích cú pháp phân tích cú pháp 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. 
+0

Cảm ơn ý tưởng, tôi sẽ kiểm tra nó :) Tôi hy vọng nó sẽ làm việc cho tất cả các trường hợp của tôi (tôi không muốn tạo ngoại lệ cho XML không phân tích cú pháp) – lad2025

2

Sử dụng WITH FUNCTION và cách tiếp cận từ Converting Long to Varchar2 nhưng vẫn còn đó là bằng cách nào đó xấu xí và overcomplicated.

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

Query:

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'; 

Tôi tin rằng cần có cách thanh lịch hơn để đạt được nó.

2

Như đã nêu bởi chính các chuyên gia, vì lý do kế thừa, không thể nội dung SUBSTR LONG thành VARCHAR2. AskTom link.

Trên other link này, bạn sẽ tìm cách để thực hiện điều đó bằng quy trình và thậm chí với chức năng nếu LONG ngắn hơn 32k DÀI.

Và chức năng này có thể được gọi sau trong truy vấn SELECT, đó là những gì bạn có thể muốn đạt được.

Các vấn đề liên quan