过程中的游标返回的值多于查询值

时间:2015-03-04 16:51:15

标签: sql oracle stored-procedures cursor

我在一个接收几个参数的过程中使用一个简单的游标。 然后,我在带有多个条件的where子句的select查询上创建一个游标,这些条件等于接收的参数。此游标应该只返回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.

2 个答案:

答案 0 :(得分:2)

您有姓名冲突。您已将本地变量调用为与列名相同,并且列名优先,如in the documentation所述:

  

如果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';

答案 1 :(得分:1)

除了Alex所说的内容之外(我不能再次建议将变量名与列名区分开来了!),为什么要使用游标for循环来插入?

您可以在一个SQL语句中执行插入操作,例如:

insert into your_table (col1, col2, ...)
select col1, col2, ...
from   your_table
where  ...

这比执行整个数据集并一次插入一行要好得多。说到数据库,尽可能多地考虑基于集合,而不是程序化!