动态选择查询在Oracle存储过程中

时间:2015-03-09 12:37:07

标签: stored-procedures oracle10g

我想在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;

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

2 个答案:

答案 0 :(得分:2)

From the documentation

  

如果 dynamic_sql_statement 是SELECT语句,并且您省略了 into_clause bulk_collect_into_clause ,那么execute_immediate_statement永远不会执行。

您的into

中没有execute immediate条款。

但是,从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 :(得分:1)

那么,

1)我想你想要使用你的catCur参数:

open catCur for 'SELECT ....';

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

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

3)你的执行立即不会以这种形式做任何事情。见EXECUTE IMMEDIATE doc

  

如果dynamic_sql_statement是SELECT语句,则省略它们   然后是into_clause和bulk_collect_into_clause   execute_immediate_statement永远不会执行。例如,这个   语句永远不会递增序列: