Sql 执行立即命令,不使用select into

Sql 执行立即命令,不使用select into,sql,oracle,plsql,Sql,Oracle,Plsql,我有下面的代码,可以正常工作 SET SERVEROUTPUT ON; DECLARE cols CLOB; BEGIN SELECT LISTAGG('"' || column_name || '"', ',') WITHIN GROUP( ORDER BY column_name ) INTO c

我有下面的代码,可以正常工作

SET SERVEROUTPUT ON;

DECLARE
    cols CLOB;
BEGIN
    SELECT
        LISTAGG('"'
                || column_name
                || '"', ',') WITHIN GROUP(
            ORDER BY
                column_name
        )
    INTO cols
    FROM
        all_tab_columns
    WHERE
        lower(table_name) = 'd_dialler_brut'
        AND column_name LIKE 'REASON%';

    dbms_output.put_line(cols);
END;
但是,如果我尝试下面的代码,它会抛出下面的错误

错误报告- ORA-00905:缺少关键字 ORA-06512:在第20行 90500000-缺少关键字

SET SERVEROUTPUT ON;

DECLARE
    cols        CLOB;
    vstr_cols   CLOB;
BEGIN
    vstr_cols := q'[
    SELECT
        LISTAGG('"'
                || column_name
                || '"', ',') WITHIN GROUP(
            ORDER BY
                column_name
        )
    INTO cols
    FROM
        all_tab_columns
    WHERE
        lower(table_name) = 'd_dialler_brut'
        AND column_name LIKE 'REASON%']'
    ;
    EXECUTE IMMEDIATE ( vstr_cols );
    dbms_output.put_line(cols);
END;
第二个代码有什么问题?如何避免该错误?

从正在生成的SELECT语句中删除INTO子句,并将其添加到EXECUTE IMMEDIATE语句中

vstr_cols := q'[
SELECT
    LISTAGG('"'
            || column_name
            || '"', ',') WITHIN GROUP(
        ORDER BY
            column_name
    )
FROM
    all_tab_columns
WHERE
    lower(table_name) = 'd_dialler_brut'
    AND column_name LIKE 'REASON%']'
;

EXECUTE IMMEDIATE vstr_cols
             INTO cols;
当然,我首先会质疑使用动态SQL是否合适。如果您可以使用静态SQL做一些事情,那么您确实应该使用静态SQL

我还强烈建议您在执行SQL语句之前,记录SQL语句或使用dbms_输出将其写出。否则,您将更加难以调试。

从正在生成的SELECT语句中删除INTO子句,并将其添加到EXECUTE IMMEDIATE语句中

vstr_cols := q'[
SELECT
    LISTAGG('"'
            || column_name
            || '"', ',') WITHIN GROUP(
        ORDER BY
            column_name
    )
FROM
    all_tab_columns
WHERE
    lower(table_name) = 'd_dialler_brut'
    AND column_name LIKE 'REASON%']'
;

EXECUTE IMMEDIATE vstr_cols
             INTO cols;
当然,我首先会质疑使用动态SQL是否合适。如果您可以使用静态SQL做一些事情,那么您确实应该使用静态SQL


我还强烈建议您在执行SQL语句之前,记录SQL语句或使用dbms_输出将其写出。否则,您将使调试变得更加困难。

谢谢。不确定在执行SQL语句之前记录它是什么意思。另外,在这种情况下,静态SQL与动态SQL相比有什么好处?@jeiv-Logging意味着将其写入表或应用程序实现的任何日志机制,以便在出现错误时,您可以确切地看到动态生成的查询。将事物保持为静态SQL有很多好处-在编译时而不是在运行时会出现编译错误,在出现语法错误时会出现更具体的错误,Oracle会为您跟踪依赖项,您不必担心SQL注入攻击之类的问题,您的代码更易于阅读、编写和调试,和维护。@jeiv-是的,如果要创建表,需要使用动态SQL。然而,在存储过程中创建表的情况非常罕见。Oracle中的表只在安装应用程序时创建一次,而不是在运行时创建。我个人编写PL/SQL代码已经有20年了,天哪,我还没有遇到过我真的想在存储过程中创建表的情况。我见过一些第三方系统定期在运行时创建表,它们通常都很难管理。@jeiv-这完全取决于你在做什么。如果您正在执行数据仓库加载并通过完全重新加载写入临时表,那么执行截断和重新加载并不是不合理的。通过merge语句进行增量加载通常更快,但这可能并不总是实用的。我不确定您使用新创建的表中的动态透视图试图解决什么问题,所以我不确定建议什么。但是,如果其他代码不能使用动态创建的表中的数据,除非它也是动态的,我会很小心。@jeiv-比删除并重新创建表更好吗?对识别增量并通过合并加载可能是最有效的。谢谢。不确定在执行SQL语句之前记录它是什么意思。另外,在这种情况下,静态SQL与动态SQL相比有什么好处?@jeiv-Logging意味着将其写入表或应用程序实现的任何日志机制,以便在出现错误时,您可以确切地看到动态生成的查询。将事物保持为静态SQL有很多好处-在编译时而不是在运行时会出现编译错误,在出现语法错误时会出现更具体的错误,Oracle会为您跟踪依赖项,您不必担心SQL注入攻击之类的问题,您的代码更易于阅读、编写和调试,和维护。@jeiv-是的,如果要创建表,需要使用动态SQL。然而,在存储过程中创建表的情况非常罕见。Oracle中的表只在安装应用程序时创建一次,而不是在运行时创建。我个人编写PL/SQL代码已经有20年了,天哪,我还没有遇到过我真的想在存储过程中创建表的情况。我见过一些第三方系统定期在运行时创建表,它们通常都很难管理。@jeiv-这完全取决于你在做什么。如果您正在执行数据仓库加载并通过完全重新加载写入临时表,那么执行截断和重新加载并不是不合理的。通过merge语句进行增量加载通常更快,但这可能并不总是实用的。我不确定您使用新创建的表中的动态透视图试图解决什么问题,所以我不确定建议什么。但考虑到其他代码无法使用DynamicCall中的数据
我创建了一个表,除非它也是动态的,否则我会很小心。@jeiv-比删除并重新创建表更好吗?对识别增量并通过合并加载可能是最有效的方法。