在存储过程中使用带有动态 SQL 的游标
我有一个在存储过程中创建的动态 SQL 语句。 我需要使用游标迭代结果。 我很难找出正确的语法。 这就是我正在做的事情。
SELECT @SQLStatement = 'SELECT userId FROM users'
DECLARE @UserId
DECLARE users_cursor CURSOR FOR
EXECUTE @SQLStatment --Fails here. Doesn't like this
OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC asp_DoSomethingStoredProc @UserId
END
CLOSE users_cursor
DEALLOCATE users_cursor
这样做的正确方法是什么?
I have a dynamic SQL statement I've created in a stored procedure. I need to iterate over the results using a cursor. I'm having a hard time figuring out the right syntax. Here's what I'm doing.
SELECT @SQLStatement = 'SELECT userId FROM users'
DECLARE @UserId
DECLARE users_cursor CURSOR FOR
EXECUTE @SQLStatment --Fails here. Doesn't like this
OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC asp_DoSomethingStoredProc @UserId
END
CLOSE users_cursor
DEALLOCATE users_cursor
What's the right way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
游标只接受 select 语句,因此如果 SQL 确实需要动态,请将声明游标作为您正在执行的语句的一部分。 为了使下面的工作正常,您的服务器必须使用全局游标。
如果需要避免使用全局游标,还可以将动态 SQL 的结果插入到临时表中,然后使用该表来填充游标。
A cursor will only accept a select statement, so if the SQL really needs to be dynamic make the declare cursor part of the statement you are executing. For the below to work your server will have to be using global cursors.
If you need to avoid using the global cursors, you could also insert the results of your dynamic SQL into a temporary table, and then use that table to populate your cursor.
此代码是带有游标的动态列的一个非常好的示例,因为您不能在 @STATMENT 中使用“+”:
This code is a very good example for a dynamic column with a cursor, since you cannot use '+' in @STATEMENT:
通过 ODBC 连接使用非关系数据库(IDMS?)是游标和动态 SQL 似乎是唯一途径的时代之一。
需要 45 分钟才能响应,而重写为使用不带 in 子句的键集将在 1 秒内运行:
如果 B 列的 in 语句包含 1145 行,则使用游标创建单独的语句并将它们作为动态 SQL 执行要快得多比使用 in 子句。 傻嘿?
是的,在关系数据库中没有时间应该使用游标。 我简直不敢相信我遇到过光标循环速度快了几个数量级的实例。
Working with a non-relational database (IDMS anyone?) over an ODBC connection qualifies as one of those times where cursors and dynamic SQL seems the only route.
takes 45 minutes to respond while re-written to use keysets without the in clause will run in under 1 second:
If the in statement for column B contains 1145 rows, using a cursor to create indidivudal statements and execute them as dynamic SQL is far faster than using the in clause. Silly hey?
And yes, there's no time in a relational database that cursor's should be used. I just can't believe I've come across an instance where a cursor loop is several magnitudes quicker.
首先,尽可能避免使用光标。 当您似乎离不开时,可以使用以下一些资源来根除它:
那里丢失光标的 15 种方法...第 1 部分,简介
Row-没有游标的按行处理
尽管如此,您可能还是会被一个问题困扰——我从您的问题中了解到的信息不足以确定其中任何一个都适用。 如果是这种情况,您就会遇到不同的问题 - 游标的 select 语句必须是实际 SELECT 语句,而不是 EXECUTE 语句。 你被困住了。
但请参阅 cmsjr(在我写作时出现的)关于使用临时表的答案。 我会比“普通”游标更避免使用全局游标......
First off, avoid using a cursor if at all possible. Here are some resources for rooting it out when it seems you can't do without:
There Must Be 15 Ways To Lose Your Cursors... part 1, Introduction
Row-By-Row Processing Without Cursor
That said, though, you may be stuck with one after all--I don't know enough from your question to be sure that either of those apply. If that's the case, you've got a different problem--the select statement for your cursor must be an actual SELECT statement, not an EXECUTE statement. You're stuck.
But see the answer from cmsjr (which came in while I was writing) about using a temp table. I'd avoid global cursors even more than "plain" ones....
最近从 Oracle 切换到 SQL Server(雇主偏好)后,我注意到 SQL Server 中的游标支持滞后。 游标并不总是邪恶的,有时需要,有时更快,有时比尝试通过重新排列或添加优化提示来调整复杂查询更干净。 “游标是邪恶的”观点在 SQL Server 社区中更为突出。
所以我猜这个答案是改用Oracle或者给MS一个线索。
for
循环隐式定义/打开/关闭光标!)After recently switching from Oracle to SQL Server (employer preference), I notice cursor support in SQL Server is lagging. Cursors are not always evil, sometimes required, sometimes much faster, and sometimes cleaner than trying to tune a complex query by re-arranging or adding optimization hints. The "cursors are evil" opinion is much more prominent in the SQL Server community.
So I guess this answer is to switch to Oracle or give MS a clue.
for
loop implicitly defines/opens/closes the cursor!)SQL Server 中的另一个选项是对存储过程中的表变量进行所有动态查询,然后使用游标来查询和处理它。 至于可怕的光标争论:),我看到的研究表明,在某些情况下,如果设置正确,光标实际上可以更快。 当所需的查询太复杂,或者根本不可能(对我来说;))时,我自己使用它们。
Another option in SQL Server is to do all of your dynamic querying into table variable in a stored proc, then use a cursor to query and process that. As to the dreaded cursor debate :), I have seen studies that show that in some situations, a cursor can actually be faster if properly set up. I use them myself when the required query is too complex, or just not humanly (for me ;) ) possible.
这段代码可能对你有用。
sql server中游标的使用示例
this code can be useful for you.
example of cursor use in sql server