动态转换更新语句以选择

时间:2019-07-05 04:27:44

标签: sql oracle

我想在PL / SQL中将更新语句动态转换为选择语句。

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

2 个答案:

答案 0 :(得分:2)

如果查询是动态的,则可以尝试以下操作:

-- 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<>fiddle demo

答案 1 :(得分:1)

您是否真的需要动态修改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,那么您就痛苦不堪。几乎不可能正确地100%解析SQL,除非可以保证输入的SQL符合较小的值范围。

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