我创建了一个返回一些数据的游标。然后,我希望在返回的数据中有一个if语句,用于检查游标中是否存在“test_field”字段,其中test_field2 ='A'。我很难在if语句上使我的语法正确,并且无法在线找到任何指针。
CURSOR test_cur IS
SELECT *
FROM test
where name=pk_name;
BEGIN
FOR trec IN test_cur LOOP
--The following line where my syntax is incorrect
IF trec.test_field EXISTS IN test_cur WHERE trec.test_field2 = 'A' THEN
{logic code to go here}
END IF;
...
示例数据:
name | test_field | test_field2
--------------------------------------
x | 101 | ROL
x | 101 | A
x | 102 | ROL
x | 103 | ROL
在游标的第一个循环中,我们有以下内容:
trec.name=x
trec.field=101
trec.field2=ROL
我想要它做的是,意识到还有另一行(y),其中test_field = 101和test_field2 ='A',因此进入if语句。
答案 0 :(得分:0)
这种语法对我来说看起来不合逻辑,AFAIK你不能这样做
解决方案是
IF trec.test_field is not null and trec.test_field2 = 'A'
答案 1 :(得分:0)
我在这里猜测,当你说'trec.test_fields存在于test_field = trec.test_field'时,你的意思是你的程序中有一个名为test_field
的单独变量。如果是这种情况,将变量的名称更改为strTest_field
,以防止命名变量和表中字段之间的冲突,并将光标更改为:
CURSOR test_cur IS
SELECT *
FROM test t
where t.name = pk_name AND
t.test_field = strTest_field AND
t.test_field2 = 'A'
分享并享受。
答案 2 :(得分:0)
您无法查看以后的光标记录,多次运行光标会很昂贵,无论如何都可能无用。
您可以在光标中对数据进行排序,以便始终将'A'
记录放在首位,然后使用跟踪变量来查看当前'A'
是否有name
条记录/ test_field
组合:
DECLARE
last_name test.name%TYPE := null;
last_test_field test.test_field%TYPE := null;
has_a BOOLEAN := false;
CURSOR cur IS
SELECT name, test_field, test_field2
FROM test
WHERE name='x'
ORDER BY name, test_field, test_field2;
-- assumes 'A' actually comes first
BEGIN
FOR rec IN cur LOOP
-- reset tracking variables if major values change
IF last_name IS NULL OR last_name != rec.name
OR last_test_field != rec.test_field
THEN
last_name := rec.name;
last_test_field := rec.test_field;
has_a := (rec.test_field2 = 'A');
END IF;
IF has_a THEN
DBMS_OUTPUT.PUT_LINE('name ' || rec.name || ' test_field '
|| rec.test_field || ' test_field2 ' || rec.test_field2
|| ' matched condition');
END IF;
END LOOP;
END;
/
name x test_field 101 test_field2 A matched condition
name x test_field 101 test_field2 ROL matched condition
PL/SQL procedure successfully completed.
更简洁的方法可能是为游标中的每条记录添加一个标志,使用分析函数来结果集中的'偷看';再次假设您的'A'
值实际上按字母顺序排在第一位,如果不是,则需要调整函数以获得实际值:
SELECT name, test_field, test_field2,
first_value(test_field2)
over (partition by name, test_field
order by test_field2) as has_a
-- assumes 'A' actually comes first
FROM test;
NAME TEST_FIELD TEST_FIELD HAS_A
---------- ---------- ---------- ----------
x 101 A A
x 101 ROL A
x 102 ROL ROL
x 103 ROL ROL
...甚至更好,因为这不依赖于目标值的字母顺序,也会给你一个更清晰的结果:
SELECT name, test_field, test_field2,
MAX(CASE WHEN test_field2 = 'A' THEN 'true' END)
OVER (PARTITION BY name, test_field) AS has_a
FROM test;
NAME TEST_FIELD TEST_FIELD HAS_
---------- ---------- ---------- ----
x 101 ROL true
x 101 A true
x 102 ROL
x 103 ROL
将它放在光标中会给出:
DECLARE
CURSOR cur IS
SELECT name, test_field, test_field2,
MAX(CASE WHEN test_field2 = 'A' THEN 'true' END)
OVER (PARTITION BY name, test_field) AS has_a
FROM test
WHERE name='x'
ORDER BY name, test_field, test_field2 DESC;
-- forcing us to see ROL first, just to show it works
BEGIN
FOR rec IN cur LOOP
IF rec.has_a = 'true' THEN
DBMS_OUTPUT.PUT_LINE('name ' || rec.name || ' test_field '
|| rec.test_field || ' test_field2 ' || rec.test_field2
|| ' matched condition');
END IF;
END LOOP;
END;
/
name x test_field 101 test_field2 ROL matched condition
name x test_field 101 test_field2 A matched condition
PL/SQL procedure successfully completed.
请注意,这也不会强制您在循环中首先处理'A'
记录,这可能重要也可能不重要 - 可能不是因为您在示例中根本没有订购。
答案 3 :(得分:0)
如果我正确理解了您的查询,那么您只能向前看。如果是这样,您必须知道定义订单的字段。我在下面给出了模板。
解决语法问题的具体声明是:
FOR trec IN test_cur LOOP - 我的语法不正确的以下行
SELECT COUNT(*) INTO l_count FROM test
where name= trec.test_field AND test_field2 = 'A'
and key > trec.key
--this condition specifies if we need to look only further
;
if l_count>0 then
{logic code to go here}
END IF;
及以下重述了完整的模板:
CURSOR test_cur IS
SELECT *
FROM test
where name=pk_name
ORDER by --<<whatever key that helps identify order>>
;
BEGIN
FOR trec IN test_cur LOOP
--The following line where my syntax is incorrect
SELECT COUNT(*) INTO l_count FROM test
where name= trec.test_field AND test_field2 = 'A'
and key > trec.key
--this condition specifies if we need to look only further
;
if l_count>0 then
{logic code to go here}
END IF;
...
答案 4 :(得分:0)
我建议在用于游标的查询中检查此条件,如下所示:
CURSOR test_cur IS
SELECT TEST.*,
CASE
WHEN EXISTS
(SELECT 1
FROM TEST T
WHERE T.TEST_FIELD = TEST.TEST_FIELD
AND T.TEST_FIELD2 = 'A')
THEN
1
ELSE
0
END
HAS_A
FROM TEST
WHERE NAME=PK_NAME;
BEGIN
FOR trec IN test_cur LOOP
--The following line where my syntax is incorrect
IF trec.has_a = 1 THEN
{logic code to go here}
END IF;
...