存储过程:光标坏了?
Posted
技术标签:
【中文标题】存储过程:光标坏了?【英文标题】:Stored Procedure: Cursor is bad? 【发布时间】:2012-06-05 21:42:12 【问题描述】:我在某处读到 99% 的时间不需要使用光标。
但我想不出在以下情况下除了使用光标之外的任何其他方式。
Select t.flag
From Dual t;
假设这会返回 4 行 'Y'
或 'N'
。我希望该过程在找到'Y'
时触发某些东西。我通常声明一个游标并循环直到%NOTFOUND
。请告诉我是否有更好的方法。
另外,如果您有任何想法,什么时候是使用光标的最佳时间?
编辑:不是插入标志,而是如果我想做 “如果 'Y'
然后触发某些东西”?
【问题讨论】:
wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them ***.com/questions/1479680/… 在您的查询中添加where t.flag = 'Y'
? ...INSERT INTO tbl_flag (<column list>) VALUES (<values>) WHERE (SELECT COUNT(*) FROM Dual t where t.flag = 'Y') > 1
mysql、T-SQL 和dual
/%NOTFOUND
(暗示Oracle)?
是的,它是甲骨文。对此感到抱歉...正如我编辑过的那样,如果 Select 查询具有“Y”,我会尝试触发
【参考方案1】:
你的情况肯定落入 99%。
您可以使用insert into ... select...
轻松进行条件插入。这只是一个问题或创建一个select
来返回您想要插入的结果。
如果您想为每个 'Y'
插入一条记录,请使用带有 where flag = 'Y'
的查询。如果您只想根据是否至少有一个'Y'
插入一条记录,则可以将distinct
添加到查询中。
当您使事情变得更复杂时,光标很有用。例如,当需要在一个表中插入或更新记录时,我使用游标,并且还为每条记录插入或更新一条或多条记录到其他几张表中。
【讨论】:
触发一些东西怎么样?如果它找到“Y”,则放入一些已创建的值或执行某些操作? @sayhaha:那你可以使用if exists(select * from Dual where Flag = 'Y')
。【参考方案2】:
类似这样的:
INSERT INTO TBL_FLAG (col)
SELECT ID FROM Dual where flag = 'Y'
当使用基于集合而不是过程操作时,您通常会看到性能提升,因为大多数现代 DBMS 都设置为执行基于集合的操作。你可以阅读更多here。
【讨论】:
触发一些东西怎么样?如果它找到“Y”,则放入一些已创建的值或执行某些操作? 我不确定你在问什么,但在这种情况下你不需要触发器。 :p 对不起所以假设我运行 select * from dual;它返回 4 行 'Y', 'N', 'N', 'Y' 然后由于系统找到 'Y' 我想从 TABLE1 中查询一个值并将其放入 TABLE2。【参考方案3】:这个例子不太合理..
但你总是可以写一个insert as select
声明而不是我认为你描述的内容
【讨论】:
【参考方案4】:当来自一个表的列值将在不同表的多个查询中重复使用时,最好使用游标。
假设 id_test 列的值是使用游标 CUR_TEST 从 MY_TEST_TBL 获取的。现在这个 id_test 列是 MY_TEST_TBL 中的一个外键。如果我们想使用 id_test 来插入或更新表 A_TBL、B_TBL 和 C_TBL 中的任何行,那么在这种情况下最好使用游标而不是使用复杂的查询。
希望这可能有助于理解光标的用途
【讨论】:
以上是关于存储过程:光标坏了?的主要内容,如果未能解决你的问题,请参考以下文章