我在接收几个参数的过程中使用简单的光标。 然后,我将光标放在带有多个条件的 where 子句的选择查询上,这些条件等于接收到的参数。该游标应该只返回 1 行,而不是返回多行。我发现这一点是因为我正在使用 for 循环来遍历此游标并根据此游标的值将某些内容插入到另一个表中。
当我静态地在数据库上运行查询时(如在没有 pl/sql 的情况下),我得到了我所期望的结果,但是当我从应该只返回一行的游标执行查询并在 for 循环中运行它时,循环确实多次迭代。这怎么可能?
谢谢!
编辑:
ID kind kolo kolo1 mjt salesman money date done
1 001 001 002 00013 00056 100,00 21-feb-12 N
我像这样运行光标:
Cursor linija IS
SELECT *
FROM table_x X
where x.mjt = mjt
and x.salesman = salesman
and x.kind = kind
and x.kolo1 = kolo1
and x.done = 'N';
这应该只返回一行,但我的光标返回 %rowcount 是 10。
您的姓名有冲突。您已将局部变量命名为与列名称相同的名称,并且列名称优先,如文档中所述 :
如果 SQL 语句引用的名称既属于列又属于局部变量或形式参数,则列名称优先。前四项检查始终为真(除非您有空值),因此您将获得具有
注意: 当变量或参数名称被解释为列名称时,数据可能会被无意中删除、更改或插入。
done = 'N'
的每一行。将局部变量名称更改为其他名称;使用前缀来区分局部变量、参数和列是相当常见的,例如:
Cursor linija IS
SELECT *
FROM table_x X
where x.mjt = l_mjt
and x.salesman = l_salesman
and x.kind = l_kind
and x.kolo1 = l_kolo1
and x.done = 'N';
如果这是在存储过程中,而不是在匿名块中,则可以使用过程/函数名称作为前缀,有些人更喜欢这样做。例如,如果您的程序名为 myproc
,您可以这样做:
Cursor linija IS
SELECT *
FROM table_x X
where x.mjt = myproc.mjt
and x.salesman = myproc.salesman
and x.kind = myproc.kind
and x.kolo1 = myproc.kolo1
and x.done = 'N';
Cursor linija (
p_mjt table_x.mjt%type, p_salesman table_x.salesman%type,
p_kind table_x.kind%type, p_kolo1 table_x.kolo1%type
) IS
SELECT *
FROM table_x X
where x.mjt = p_mjt
and x.salesman = p_salesman
and x.kind = p_kind
and x.kolo1 = p_kolo1
and x.done = 'N';
或以光标名称作为前缀:
Cursor linija (
mjt table_x.mjt%type, salesman table_x.salesman%type,
kind table_x.kind%type, kolo1 table_x.kolo1%type
) IS
SELECT *
FROM table_x X
where x.mjt = linija.mjt
and x.salesman = linija.salesman
and x.kind = linija.kind
and x.kolo1 = linija.kolo1
and x.done = 'N';
无论哪种方式,当您打开光标时都包含参数,例如如果您无论如何在过程级别更改了变量名称:
for x in linija (l_mjt, l_salesman, l_kind, l_kolo1) loop
或者如果你没有:
for x in linija (myproc.mjt, myproc.salesman, myproc.kind, myproc.kolo1) loop
您可以只在一条 SQL 语句中进行插入,例如:
insert into your_table (col1, col2, ...)
select col1, col2, ...
from your_table
where ...
这比遍历整个数据集并一次插入每一行要好得多。当谈到数据库时,尽可能多地考虑基于集合,而不是程序!