Search code examples
databaseoracle-databaseoracle12c

Query using a statement within a VARCHAR2 column


Is there a way for a select statement to include in the WHERE clause a statement that is contained within the table? For example, the following table:

CREATE TABLE test_tab(
    date_column DATE,
    frequency NUMBER,
    test_statement VARCHAR2(255)
)
/

If

MOD(SYSDATE - DATE, frequency) = 0

were contained within the column test_statement, is there a way to select rows where this is true? The test_statement will vary and not be the same throughout the table. I am able to do this in PL/SQL but looking to do this without the use of PL/SQL.


Solution

  • This kind of dynamic SQL in SQL can created with DBMS_XMLGEN.getXML. Although the query looks a bit odd so you might want to consider a different design.

    First, I created a sample table and row using your DDL. I'm not sure exactly what you're trying to do with the conditions, so I simplified them into two rows with simpler conditions. The first row matches the first condition, and neither row matches the second condition.

    --Create sample table and row that matches the condition.
    CREATE TABLE test_tab(
        date_column DATE,
        frequency NUMBER,
        test_statement VARCHAR2(255)
    )
    /
    
    insert into test_tab values(sysdate, 1, 'frequency = 1');
    insert into test_tab values(sysdate, 2, '1=2');
    commit;
    

    Here's the large query, and it only returns the first row, which only matches the first condition.

    --Find rows where ROWID is in a list of ROWIDs that match the condition.
    select *
    from test_tab
    where rowid in
    (
        --Convert XMLType to relational data.
        select the_rowid
        from
        (
            --Convert CLOB to XMLType.
            select xmltype(xml_results) xml_results
            from
            (
                --Create a single XML file with the ROWIDs that match the condition.
                select dbms_xmlgen.getxml('
                    select rowid
                    from test_tab where '||test_statement) xml_results
                from test_tab
            )
            where xml_results is not null
        )
        cross join
        xmltable
        (
            '/ROWSET/ROW'
            passing xml_results
            columns
                the_rowid varchar2(128) path 'ROWID'
        )
    );