动态转换更新语句以选择



我想将一个更新语句转换为pl/sql中的选择语句。

例如 update temp set b='apple' where a=1应该转换为 select count(*) from temp where a=1

如果您的查询是动态的,则可以尝试以下内容:

-- DATA PREPARATION
WITH MY_QUERY ( QRY ) AS (
    SELECT
        q'#update temp set b='apple' where a=1#'
    FROM
        DUAL
)
-- ACTUAL QUERY
SELECT
    'SELECT COUNT(*) FROM '
    || TABLENAME
    || ' '
    || WHERE_CLAUSE AS UPDATED_QUERY
FROM
    (
        SELECT
            REGEXP_SUBSTR(QRY, '[^ ]+', 1, 2) AS TABLENAME,
            REGEXP_SUBSTR(QRY, 'where (.)+$', 1, 1) AS WHERE_CLAUSE
        FROM
            MY_QUERY
    );

--
OUTPUT:
--
SELECT COUNT(*) FROM temp where a=1

您的查询(字符串(包裹在替代引用的字符串(q'#....#'(中,因为它包含引号。

db<>小提琴演示

您是否真的需要动态修改SQL,还是只是想修改行的行数?如果您只需要修改行数,则SQL%ROWCOUNT可以提供:

create table temp as
select 1 a, 'orange' b from dual;
declare
    v_sql varchar2(32767) := q'[update temp set b='apple' where a=1]';
begin
    execute immediate v_sql;
    dbms_output.put_line('Rows updated: '||sql%rowcount);
end;
/

输出:

Rows updated: 1

如果您确实需要动态修改SQL,那么您将处于痛苦的世界中。解析SQL 100%正确地几乎是不可能的,除非您可以保证输入SQL符合少量值。

如果您需要解析和重新格式化SQL,希望您可以在Tejash的答案中使用正则表达式。如果您需要更强大的功能,请查看我的开源程序PLSQL_LEXER。如果您仍然需要更多的功率,请看一下Antlr。但是,随着解决方案变得越来越强大,它们成倍增长。

最新更新