Oracle 存储过程中的动态 Select 查询

Dynamic Select query In Oracle Stored Procedure

我想在 Oracle 中编写一个传递动态值的存储过程,如下所示:

create or replace PROCEDURE DETAILDISCDATA2
(
  USERTYPE IN VARCHAR2,
  BID IN NUMBER,
  SORT_COLUMN IN VARCHAR2,
  SORT_ORDER IN VARCHAR2,
  catCur OUT SYS_REFCURSOR
) AS 
COUNTRY_CODE VARCHAR2(10) := 'USA';

v_sql varchar2(1000);
BEGIN

v_sql := 'SELECT bd.*, BD.ATS_ITEM_LIST_PRICE_UNIT as UNIT_NORMAL_NET, BD.ITEM_LIST_PRICE_TOTAL as NORMAL_NET '
' FROM bdetail BD '
' LEFT OUTER JOIN CATALOG_SCH_DISC DD '
' ON BD.MAT_NR       = DD.PRODUCT_NO '
' AND DD.COUNTRY_CODE= :a ';
' AND BD.Id = :b  order by :c :d';

EXECUTE IMMEDIATE v_sql using COUNTRY_CODE, BID ,SORT_COLUMN,SORT_ORDER;

END DETAILDISCDATA2;

当我执行这个存储过程时,它显示没有数据的输出,但是如果我 运行 使用静态值的相同查询给出正确的输出

From the documentation:

If dynamic_sql_statement is a SELECT statement, and you omit both into_clause and bulk_collect_into_clause, then execute_immediate_statement never executes.

您的 execute immediate 中没有 into 子句。

但是,从 OUT 参数看来,您真正想要的是打开该查询的引用游标:

OPEN catCur FOR v_sql using COUNTRY_CODE, BID ,SORT_COLUMN,SORT_ORDER;

您不能在 order_by 中使用绑定变量指定列名。您需要将它们连接起来,所以它将是:

v_sql := 'SELECT bd.*, BD.ATS_ITEM_LIST_PRICE_UNIT as UNIT_NORMAL_NET, '
|| ' BD.ITEM_LIST_PRICE_TOTAL as NORMAL_NET '
|| ' FROM bdetail BD '
|| ' LEFT OUTER JOIN CATALOG_SCH_DISC DD '
|| ' ON BD.MAT_NR       = DD.PRODUCT_NO '
|| ' AND DD.COUNTRY_CODE= :a '
|| ' AND BD.Id = :b '
|| ' order by ' || SORT_COLUMN || ' ' || SORT_ORDER;

OPEN catCur FOR v_sql using COUNTRY_CODE, BID;

嗯,

1) 我想你想像这样使用你的 catCur 参数:

open catCur for 'SELECT ....';

然后将参数传递到其他地方 - 您想使用它的地方

2) 这部分:“... order by :c :d”将不起作用。您不能将列名作为变量传递。您必须使用列的静态名称构建语句。

3) 您的立即执行在这种形式下不会执行任何操作。见 EXECUTE IMMEDIATE doc:

If dynamic_sql_statement is a SELECT statement, and you omit both into_clause and bulk_collect_into_clause, then execute_immediate_statement never executes. For example, this statement never increments the sequence: