【问题标题】:Stored procedure output in select statementselect语句中的存储过程输出
【发布时间】:2019-01-14 21:20:31
【问题描述】:

我正在拼命地调用一个 oracle 存储过程,并让输出看起来像是来自 select 语句。

目标是将sql嵌入到其他可以执行sql查询的软件中。

这是我想做的事情的一个示例。

/* P_DELETE_THIS_TEST IS A STORED PROCEDURE WITH 4 VARCHAR2 PARAMETERS DEFINED AS IN OUT VARIABLES */

DECLARE
   char_1       VARCHAR2(255) := 'TEST';
   char_2       VARCHAR2(255) := '';
   char_3       VARCHAR2(255) := '';
   char_4       VARCHAR2(255) := '';

BEGIN
   P_DELETE_THIS_TEST(char_1, char_2, char_3, char_4);
   SELECT char_1, char_2, char_3, char_4 FROM DUAL;
END;

【问题讨论】:

  • 我没有遵循“目标是将 sql 嵌入到其他可以执行 sql 查询的软件中。”为什么其他软件不能调用您的P_DELETE_THIS_TEST() 程序并获取值?你真的想在这里做什么?
  • 其他软件无法从存储过程中获取出站值。它可以: A. 在不识别任何输出的情况下触发并忘记 SQL 语句,或 B. 从 SQL 查询中取回列。我想执行一个过程,但是让输出像从 select 语句中返回一样。如果我无法做到这一点,我想我可以传入一个 GUID 并在完成后将 proc 插入到一个虚拟表中。然后我可以在执行存储过程后查询虚拟表。这就像 C 计划或 D 计划......
  • 嗨@P.B.检查 oracle 中的表函数,我认为这将解决您的问题
  • 您的 C/D 计划听起来像是需要一个全局临时表;特定于会话会删除 GUID(如果我理解你的话)。如果您可以创建类型,流水线函数可能会起作用。但是应用程序如何执行和接收结果;它可以处理作为查询的一部分的函数调用的 ref 游标结果吗?
  • 我同意@AlexPoole 插入全局临时表,然后打开从临时表中选择的光标。一旦客户端删除会话,临时表中的数据就会消失。我认为这是一种非常合理的处理方式。

标签: oracle stored-procedures


【解决方案1】:

您可以尝试使用动态 sql。 以下 PL/SQL 块包含几个动态 SQL 示例:

DECLARE
   sql_stmt    VARCHAR2(200);
   plsql_block VARCHAR2(500);
   emp_id      NUMBER(4) := 7566;
   salary      NUMBER(7,2);
   dept_id     NUMBER(2) := 50;
   dept_name   VARCHAR2(14) := 'PERSONNEL';
   location    VARCHAR2(13) := 'DALLAS';
   emp_rec     emp%ROWTYPE;
BEGIN
   EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
   sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';
   EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;
   sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
   EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
   plsql_block := 'BEGIN emp_pkg.raise_salary(:id, :amt); END;';
   EXECUTE IMMEDIATE plsql_block USING 7788, 500;
   sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1
      RETURNING sal INTO :2';
   EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;
   EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num'
      USING dept_id;
   EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';
END;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多