运行 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
我有一个功能,如下所示。我有一个查询字符串,因为我需要用一个参数来执行它。我的问题是:如何将查询放入 "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