过程中的游标返回比查询更多的值
Cursor in procedure returning more values than query
我在接收几个参数的过程中使用了一个简单的游标。
然后,我在 select 查询上创建一个游标,其中包含一个包含多个条件的 where 子句,这些条件等于接收到的参数。此游标应该只有 return 1 行,而不是 return 多行。我发现这一点是因为我正在使用 for 循环遍历此游标并根据此游标的值将某些内容插入另一个 table。
当我 运行 静态地查询数据库时(就像没有 pl/sql 一样)我得到了我期望的结果,但是当我从一个应该只 return 的游标中进行查询时一行,并且 运行 它在 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';
这应该 return 只有一行,但我的光标 returns %rowcount 是 10。
您的名字有冲突。您已将局部变量称为与列名相同的名称,并且列名优先,如前所述 in the documentation:
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
Caution:
When a variable or parameter name is interpreted as a column name, data can be deleted, changed, or inserted unintentionally.
前四项检查始终为真(除非您有空值),因此您将获得包含 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';
如果这是在存储过程中,而不是在匿名块中,您可以使用 procedure/function 名称作为前缀,有些人更喜欢这样做。例如,如果您的过程被称为 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';
除了 Alex 所说的(我不能赞同他的建议以充分区分变量名和列名!),为什么要使用游标 for 循环来进行插入?
您可以只在一个 SQL 语句中插入,例如:
insert into your_table (col1, col2, ...)
select col1, col2, ...
from your_table
where ...
这比遍历整个数据集并一次插入每一行要好得多。说到数据库,尽可能多地考虑基于集合,而不是程序!
我在接收几个参数的过程中使用了一个简单的游标。 然后,我在 select 查询上创建一个游标,其中包含一个包含多个条件的 where 子句,这些条件等于接收到的参数。此游标应该只有 return 1 行,而不是 return 多行。我发现这一点是因为我正在使用 for 循环遍历此游标并根据此游标的值将某些内容插入另一个 table。
当我 运行 静态地查询数据库时(就像没有 pl/sql 一样)我得到了我期望的结果,但是当我从一个应该只 return 的游标中进行查询时一行,并且 运行 它在 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';
这应该 return 只有一行,但我的光标 returns %rowcount 是 10。
您的名字有冲突。您已将局部变量称为与列名相同的名称,并且列名优先,如前所述 in the documentation:
If a SQL statement references a name that belongs to both a column and either a local variable or formal parameter, then the column name takes precedence.
Caution:
When a variable or parameter name is interpreted as a column name, data can be deleted, changed, or inserted unintentionally.
前四项检查始终为真(除非您有空值),因此您将获得包含 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';
如果这是在存储过程中,而不是在匿名块中,您可以使用 procedure/function 名称作为前缀,有些人更喜欢这样做。例如,如果您的过程被称为 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';
除了 Alex 所说的(我不能赞同他的建议以充分区分变量名和列名!),为什么要使用游标 for 循环来进行插入?
您可以只在一个 SQL 语句中插入,例如:
insert into your_table (col1, col2, ...)
select col1, col2, ...
from your_table
where ...
这比遍历整个数据集并一次插入每一行要好得多。说到数据库,尽可能多地考虑基于集合,而不是程序!