SQL游标问题
我收到以下错误,但无法弄清楚为什么..SQL游标问题
消息16915,级别16,状态1,过程client_myClientsProc, 线46
名为'游标cur_keywords'已经存在。
消息16905,级别16,状态1,过程client_myClientsProc,行 游标已经打开。
然后,如果我尝试再次运行它,它说
消息208,级别16,状态0,过程client_myClientsProc线49
无效的对象名称## CLIENTS_KEYWORD。
现在,这是我试图解决,所以请多多包涵旧代码...
ALTER PROCEDURE [dbo].[client_myclientsproc]
@Keywords varchar(max),
@Delimiter varchar(10) = ' '
AS
BEGIN
SET NOCOUNT ON;
DECLARE @MYQUERY NVARCHAR(MAX);
DECLARE @tempkeyword varchar(4000)
DECLARE @TempCount INT
IF OBJECT_ID('TempDB..##CLIENTS_KEYWORD') IS NOT NULL
BEGIN
DROP TABLE ##CLIENTS_KEYWORD
END
ELSE
BEGIN
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
END
IF OBJECT_ID('TempDB..##TEMP_CLIENTS_KEYWORD') IS NOT NULL
BEGIN
DROP TABLE ##TEMP_CLIENTS_KEYWORD
END
ELSE
BEGIN
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(productid int)
END
SET @MYQUERY = 'SELECT clientID, Client_Name FROM MYCLIENTS WHERE ClientID IN ';
IF(@Delimiter<>'none')
BEGIN
DECLARE cur_keywords CURSOR FOR
select value from SC_Split(@Keywords,@Delimiter)
OPEN cur_keywords
FETCH NEXT FROM cur_keywords into @tempkeyword
INSERT ##CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @tempkeyword
WHILE @@FETCH_STATUS = 0
FETCH NEXT FROM cur_keywords into @tempkeyword
INSERT ##TEMP_CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @tempkeyword
select @TempCount=COUNT(client_id) from ##TEMP_CLIENTS_KEYWORD
IF(@TempCount<>0)
BEGIN
DELETE FROM ##CLIENTS_KEYWORD WHERE client_id NOT IN(SELECT client_id from ##TEMP_CLIENTS_KEYWORD)
INSERT ##CLIENTS_KEYWORD (client_id) (select client_id from ##TEMP_CLIENTS_KEYWORD)
END
CLOSE cur_keywords
DEALLOCATE cur_keywords
END
ELSE
BEGIN
print(@Keywords)
INSERT ##CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @Keywords
END
SET @MYQUERY = @MYQUERY + '(SELECT * FROM ##CLIENTS_KEYWORD)'
SET @MYQUERY = @MYQUERY + ' ORDER BY NAME'
print @MYQUERY
EXEC SP_EXECUTESQL @MYQUERY
END
GO
================= ===
获得通过关键词代码客户
CREATE PROCEDURE [dbo].[getClientsByKeyword]
@Keyword varchar(max)
AS
BEGIN
SET NOCOUNT ON;
select
DISTINCT(clients.clientID)
from
Clients_Table clients
left join clientNumber cn on cn.clientid=clients.clientid
where
clients.activeind = 1
and (clients.Name like '%' + @Keyword + '%'
or clients.clientNum LIKE '%' + @Keyword + '%'
or cn.clientN like '%' + @Keyword + '%')
END
GO
- 你
OPEN
,FETCH
,WHILE
,CLOSE
和DEALLOCATE
是错误的。 - 您的临时表需要每次创建。
试试这个重构的脚本。修改为您需要:
DECLARE @tempkeyword varchar(4000)
DECLARE @TempCount INT
IF OBJECT_ID('TempDB..##CLIENTS_KEYWORD') IS NOT NULL
DROP TABLE ##CLIENTS_KEYWORD
CREATE TABLE ##CLIENTS_KEYWORD(client_id int)
IF OBJECT_ID('TempDB..##TEMP_CLIENTS_KEYWORD') IS NOT NULL
DROP TABLE ##TEMP_CLIENTS_KEYWORD
CREATE TABLE ##TEMP_CLIENTS_KEYWORD(productid int)
SET @MYQUERY = 'SELECT clientID, Client_Name FROM MYCLIENTS WHERE ClientID IN ';
IF(@Delimiter<>'none')
BEGIN
DECLARE cur_keywords CURSOR FOR
SELECT value FROM SC_Split(@Keywords,@Delimiter)
OPEN cur_keywords
FETCH NEXT FROM cur_keywords into @tempkeyword
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM cur_keywords into @tempkeyword
INSERT ##CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @tempkeyword
INSERT ##TEMP_CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @tempkeyword
SELECT @TempCount=COUNT(client_id) from ##TEMP_CLIENTS_KEYWORD
IF(@TempCount<>0)
BEGIN
DELETE FROM ##CLIENTS_KEYWORD
WHERE client_id NOT IN(SELECT client_id from ##TEMP_CLIENTS_KEYWORD);
INSERT ##CLIENTS_KEYWORD (client_id)
SELECT client_id from ##TEMP_CLIENTS_KEYWORD;
END
END
CLOSE cur_keywords
DEALLOCATE cur_keywords
END
ELSE
BEGIN
print(@Keywords)
INSERT ##CLIENTS_KEYWORD(client_id) exec getClientsByKeyword @Keywords
END
SELECT @[email protected] + '(SELECT * FROM ##CLIENTS_KEYWORD) ORDER BY NAME'
print @MYQUERY
EXEC SP_EXECUTESQL @MYQUERY
END
做的存储过程的错误了以前?它看起来像CLOSE
和DEALLOCATE
语句没有运行,这可能会发生,如果代码遇到错误,因为代码或其他方法中没有TRY..CATCH
,以确保游标已被正确清除。尝试断开连接(或在同一连接中手动运行CLOSE
和DEALLOCATE
)并再次运行。
第二个错误可能是由于类似的原因 - 糟糕的清理。当您输入存储过程时,代码DROP
是临时表(如果它已存在)。 CREATE
位于该声明的ELSE
部分。这意味着如果表格已经存在,那么它将会被重新制作并且不会被重新创建。
Gotcha感谢您的意见 – user710502
没有建立测试表为此我真的不知道你的代码是做什么,但我想你也许能避免使用光标在所有基于下面的东西。
;WITH C
AS (select clients.clientID,
clients.Name,
clients.clientNum,
cn.clientN
from Clients_Table clients
left join clientNumber cn
on cn.clientid = clients.clientid
AND clients.activeind = 1)
select value,
clients.clientID
from SC_Split(@Keywords, @Delimiter)
JOIN C
ON (C.Name like '%' + value + '%'
or C.clientNum LIKE '%' + value + '%'
or C.clientN like '%' + value + '%')
你在什么版本的SQL Server? –
我的版本是2008 – user710502
getClientsByKeyword是做什么的?用一个简单的连接来代替它会简单吗?或者(如果更复杂的话)把逻辑放到一个表值函数中,那么你可以完全放下光标。 –