运行 for in 循环内的查询脚本 (Oracle)

Run a query script inside a for in loop (Oracle)

我有一个功能,如下所示。我有一个查询字符串,因为我需要用一个参数来执行它。我的问题是:如何将查询放入 "for"?我试过

EXECUTE IMMEDIATE query_string 

在我的 for 循环中,但它不起作用。

有人吗?

此致!

create or replace FUNCTION RO_FUN_TOTAL_SCORE_DATE_PORTAL
(
  v_DATE_FIELD  IN VARCHAR2
) RETURN RO_OBJ_NESTED_TOTAL_SCORE IS
  v_ret               RO_OBJ_NESTED_TOTAL_SCORE;
  query_string       VARCHAR2(1000);
BEGIN
  /*Initialize object type to save data*/
  v_ret := RO_OBJ_NESTED_TOTAL_SCORE();

  query_string := 'SELECT ROUND(AVG(generic_score),2) AS score,
    yrp.comment_date_pk AS comment_date,
    yrp.hot_id_pk AS hot_id,
    yp.portal_id_pk AS portal_id,
    AVG(total_opinions) AS total_opinions
   FROM yrportalreview yrp JOIN yrhotellinks yrh ON yrp.hot_id_pk =
    yrh.hot_id
    AND yrp.portal_id_pk = yrh.portal_id AND yrp.comment_date.pk = ' ||    
    v_DATE_FIELD || 
  ' WHERE yrp.hot_id_pk IN (92, 27)
    AND concept_id_pk = 1
    AND yp.active = 1
   GROUP BY hot_id_pk,
    yp.portal_id_pk,
    yrp.comment_date_pk';

FOR I IN (EXECUTE IMMEDIATE query_string)
  LOOP
    /*insert in table type rows with data*/
    v_ret.extend;
    v_ret(v_ret.count) := RO_OBJ_TOTAL_SCORE_DATE_PORTAL(i.score, 
      i.comment_date, i.hot_id, i.portal_id, i.total_opinions);
  END LOOP;
  RETURN v_ret;
END RO_FUN_TOTAL_SCORE_DATE_PORTAL;

您不应将数据串联到您的查询中。使用绑定变量。阅读 SQL 注入和硬解析,了解应该使用绑定变量的两个原因。

您可以尝试如下操作(完全不需要循环):

  create or replace FUNCTION RO_FUN_TOTAL_SCORE_DATE_PORTAL
  (
    v_DATE_FIELD  IN VARCHAR2
  ) RETURN RO_OBJ_NESTED_TOTAL_SCORE IS
    v_ret               RO_OBJ_NESTED_TOTAL_SCORE;

  BEGIN

    SELECT RO_OBJ_TOTAL_SCORE_DATE_PORTAL
              (ROUND(AVG(generic_score),2)  -- score,
              ,yrp.comment_date_pk          -- comment_date
              ,yrp.hot_id_pk                -- hot_id
              ,yp.portal_id_pk              -- portal_id
              ,AVG(total_opinions))         -- total_opinions
    BULK COLLECT INTO v_ret
     FROM yrportalreview yrp 
     JOIN yrhotellinks yrh 
           ON yrp.hot_id_pk = yrh.hot_id
           AND yrp.portal_id_pk = yrh.portal_id 
           AND yrp.comment_date.pk = v_DATE_FIELD 
     WHERE yrp.hot_id_pk IN (92, 27)
      AND concept_id_pk = 1
      AND yp.active = 1
     GROUP BY hot_id_pk,
      yp.portal_id_pk,
      yrp.comment_date_pk';

    RETURN v_ret;
  END RO_FUN_TOTAL_SCORE_DATE_PORTAL;

适用于测试类型和数据的类似内容:

create or replace function f_test(v_date_field in varchar2) return t_test_tab is

  v_ret t_test_tab;
  v_sql varchar2(4000);
begin
  v_sql := 'select t_test_row(id, date1) from test where date1 = '||v_date_field;
  execute immediate v_sql bulk collect into v_ret;
  return v_ret;
end f_test;

数据定义和测试:

create table test (id number, date1 date, date2 date, date3 date);
insert into test values (1, date '2015-01-01', date '2015-01-01', date '2015-01-02');
insert into test values (2, date '2015-01-02', date '2015-01-01', date '2015-01-02');

create type t_test_row is object (id number, date1 date);
create type t_test_tab is table of t_test_row;

select * from table(f_test('DATE2'));

ID  DATE1
--  ----------
 1  2015-01-01