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;
当我执行这个存储过程时,它显示没有数据的输出,但是如果我 运行 使用静态值的相同查询给出正确的输出
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:
我想在 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;
当我执行这个存储过程时,它显示没有数据的输出,但是如果我 运行 使用静态值的相同查询给出正确的输出
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: