【问题标题】:Creating procedure with dynamic SQL使用动态 SQL 创建过程
【发布时间】:2021-05-04 15:32:25
【问题描述】:

以下是说明:

一家公司希望允许客户通过选择产品名称或 描述,然后键入搜索词。使用本机动态 SQL,创建一个 返回产品名称、描述和价格基础的过程名称 SEARCH_SP 根据用户的搜索条件。该过程需要处理返回的多行。

这是我目前的代码。

CREATE OR REPLACE PROCEDURE search_sp (product_name IN VARCHAR2,
                                        description IN VARCHAR2,
                                        price_based IN NUMBER             
                                        )
AS

BEGIN
    SELECT customer.product.name, customer.description, customer.price
    FROM dbo.customer
    WHERE customer.description = @SEARCH.customer.product.name = @SEARCH
END;
/

EXECUTE IMMEDIATE plsql_block
    USING IN OUT new_product_name, new_description, new_price_based;
    
END;
/

我遇到了编译错误等等。任何帮助或建议将不胜感激。

【问题讨论】:

  • 您遇到的具体错误是什么?
  • @MichaelD,这是我得到的错误。 Warning: Procedure created with compilation errors. BEGIN IMMEDIATE plsql_block; END; * ERROR at line 1: ORA-06550: line 1, column 17: PLS-00103: Encountered the symbol "PLSQL_BLOCK" when expecting one of the following: := . ( @ % ; The symbol ":=" was substituted for "PLSQL_BLOCK" to continue. SP2-0734: unknown command beginning "USING IN O..." - rest of line ignored. SP2-0042: unknown command "END" - rest of line ignored. Warning: Procedure created with compilation errors

标签: sql oracle plsql object-oriented-database


【解决方案1】:

动态 SQL?做什么的?让你的生活比应有的更悲惨? 直接 SQL有什么问题?

我建议一个函数。为什么?你应该返回结果。如果它是一个过程,它必须有一个OUT 参数。如果是这样,那么它就是一个函数。

这就是我的做法;看看它是如何工作的,如果你愿意,可以使用它(并改进)。我不认为我会在这里参与任何动态的事情,抱歉。


由于我没有您的表,我将使用 Scott 的示例模式。这是我感兴趣的数据:

SQL> select d.dname, e.ename, e.job, e.sal
  2    from dept d join emp e on e.deptno = d.deptno
  3    order by d.dname, e.job, e.sal;

DNAME          ENAME      JOB              SAL
-------------- ---------- --------- ----------
ACCOUNTING     MILLER     CLERK           1300
ACCOUNTING     CLARK      MANAGER         2450
ACCOUNTING     KING       PRESIDENT       5000
RESEARCH       SCOTT      ANALYST         3000
RESEARCH       FORD       ANALYST         3000
RESEARCH       SMITH      CLERK            800
RESEARCH       ADAMS      CLERK           1100
RESEARCH       JONES      MANAGER         2975
SALES          JAMES      CLERK            950
SALES          BLAKE      MANAGER         2850
SALES          MARTIN     SALESMAN        1250   --> for testing, I'll fetch SALESMEN
SALES          WARD       SALESMAN        1250   --> who earn 1250 USD (it's probably USD)
SALES          TURNER     SALESMAN        1500
SALES          ALLEN      SALESMAN        1600

14 rows selected.

通过它进行搜索的代码如下所示:

SQL> create or replace function search_sp
  2    (par_dname in varchar2,
  3     par_job   in varchar2,
  4     par_sal   in number
  5    )
  6    return sys_refcursor
  7  is
  8    rc sys_refcursor;
  9  begin
 10    open rc for
 11      select d.dname, e.ename, e.job, e.sal
 12        from dept d join emp e on e.deptno = d.deptno
 13        where (d.dname = par_dname or par_dname is null)
 14          and (e.job   = par_job   or par_job   is null)
 15          and (e.sal   = par_sal   or par_sal   is null);
 16    return rc;
 17  end;
 18  /

Function created.

让我们测试一下:

SQL> select search_sp(null, 'SALESMAN', 1250) from dual;

SEARCH_SP(NULL,'SALE
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

DNAME          ENAME      JOB              SAL
-------------- ---------- --------- ----------
SALES          WARD       SALESMAN        1250
SALES          MARTIN     SALESMAN        1250


SQL>

我觉得不错。

【讨论】:

  • where d.dname = coalesce(par_dname,d.dname)
  • 当然,为什么不呢,@Hogan;还有另一种方法。或 NVL。可能还有其他一些选择。
  • 谢谢。这是一个需要动态 SQL 的学校实验室项目。我宁愿使用好的旧的直接 SQL,但我不想让作业失败。
  • 还有其他答案吗?我必须使用动态 SQL,因为分配需要它。
猜你喜欢
  • 2013-07-18
  • 2019-08-05
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2014-12-08
  • 2014-02-06
相关资源
最近更新 更多