我们在定义游标的时候,无非是类似如下句子:
DECLARE MyCursor CURSOR FOR SELECT * FROM Table WHERE ID IN (1,2,4)现在想在一个存储过程中传入ID串来代替 (1,2,4)CREATE PROCEDURE UpdateRecords
@IDString varchar(4000)
ASDECLARE MyCursor CURSOR FOR 
SELECT * FROM Table WHERE ID IN (@IDString)
显然如上的语句是通不过的,那么我该如何实现这个游标呢?

解决方案 »

  1.   

    exec ‘SELECT * FROM Table WHERE ID IN (‘ + @IDString + ’)’
      

  2.   


    --定义游标只能跟查询语句.可以先把条件查询的结果放入一个临时表内操作,
    --只能想到这么多了呵呵,当做动态SQL练习
    --类似如下获取动态查询结果,希望有所帮助:---------方法一:修改拼接字符串令其符合条件(直接运行:varchar 值 '200510405101   ' 时溢出了整数列。)
    DECLARE @STR VARCHAR(100),@STR1 VARCHAR(100),@A VARCHAR(100)
    SET @STR='040405028,040405029,200510405104,200510405106'
    SET @A=''
    PRINT '原有字符串:'+@STR
    SET @STR1=@STR+','
    --PRINT @STR1
    WHILE CHARINDEX(',',@STR1)>0
    BEGIN
       SET @A=@A+''''+LEFT(@STR1,CHARINDEX(',',@STR1)-1)+''''+','
       SET @STR1=RIGHT(@STR1,LEN(@STR1)-CHARINDEX(',',@STR1))
    END
    PRINT '--------------------------------------'
    SET @A=STUFF(@A,LEN(@A),1,'')
    PRINT '修改后字符串:'+@A
    -------------------
    EXEC('SELECT SNAME FROM S WHERE S# IN('+@A+')')/*输出:
    原有字符串:040405028,040405029,200510405104,200510405106
    --------------------------------------
    修改后字符串:'040405028','040405029','200510405104','200510405106'
    --执行结果
    SNAME
    ----------
    张波      
    余俊润    
    高博      
    董广飞    (4 行受影响)*/
    -----------方法二:拼接生成查询语句
    DECLARE @STR VARCHAR(100),@STR1 VARCHAR(100),@A VARCHAR(100),@B VARCHAR(100),@RESULT VARCHAR(500)
    SET @STR='040405028,040405029,200510405104,200510405106'
    SET @B='SELECT * FROM S WHERE S#='
    SET @A=''
    SET @RESULT=''
    PRINT @STR
    SET @STR1=@STR+','
    --PRINT @STR1
    WHILE CHARINDEX(',',@STR1)>0
    BEGIN
       SET @A=''''+LEFT(@STR1,CHARINDEX(',',@STR1)-1)+''''
       SET @RESULT=@RESULT+@B+@A+' UNION ALL '
       SET @STR1=RIGHT(@STR1,LEN(@STR1)-CHARINDEX(',',@STR1))
    END
    PRINT '--------------------------------------'
    SET @RESULT=STUFF(@RESULT,LEN(@RESULT)-8,9,'')
    PRINT '生成查询语句:'+@RESULT
    EXECUTE(@RESULT) --运行
    /*输出
    040405028,040405029,200510405104,200510405106
    --------------------------------------
    生成查询语句:SELECT * FROM S WHERE S#='040405028' UNION ALL SELECT * FROM S WHERE S#='040405029' 
    UNION ALL SELECT * FROM S WHERE S#='200510405104' UNION ALL SELECT * FROM S WHERE S#='200510405106' --执行结果:
    S#              SNAME      AGE         SEX
    --------------- ---------- ----------- ----
    040405028       张波         20          F 
    040405029       余俊润        23          男
    200810405104    高博         22          男
    200810405106    董广飞        21          男(4 行受影响)
      

  3.   

    --1. 构造使用IN子句的动态Transact-SQL方法进行编号查询--a. 要查询的字段类型是数字型--查询的值列表
    DECLARE @idlist varchar(100)
    SET @idlist='1,2,3'--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
    GO--b. 要查询的字段类型是字符型
    --查询的值列表已经加上了字符串边界符
    DECLARE @idlist varchar(100)
    SET @idlist='''a'',''b''''a'',''c'''--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
    GO--查询的值列表没有字符串边界符
    DECLARE @idlist varchar(100)
    SET @idlist='a,b''a,c'--由于是字段类型是,所以在拼接时,必须为其加上字符串边界符(')
    DECLARE @s varchar(1000)
    SET @s=''''
        +REPLACE(REPLACE(@idlist,'''',''''''),',',''',''')
        +''''--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@s+')')
    GO/*=====================================================*/
    --2. 使用LIKE或者PATINDEX进行编号查询
    --查询的值列表
    DECLARE @idlist varchar(100)
    SET @idlist='1,2,3'--查询
    SELECT * FROM tbname WHERE CHARINDEX(','+RTRIM(fdname)+',',','+@idlist+',')>0
    SELECT * FROM tbname WHERE PATINDEX('%,'+RTRIM(fdname)+',%',','+@idlist+',')>0
    SELECT * FROM tbname WHERE ','+@idlist+',' LIKE '%,'+RTRIM(fdname)+',%'
    GO/*=====================================================*/
    --3. 编号查询中常见的错误
    --a. 最容易犯的错误:表达式充当表达式列表。
    DECLARE @s varchar(100)
    SET @s='1'
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    /*--结果
    id          name 
    ---------------- ------------
    1           sysobjects
    --*/SET @s='1,2,3'
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    /*--结果
    服务器: 消息 245,级别 16,状态 1,行 3
    将 varchar 值 '1,2,3' 转换为数据类型为 int 的列时发生语法错误。
    --*/
    GO--b. 生成动态Transact-SQL语句时忽略了数据类型。
    DECLARE @s varchar(100)
    SET @s='U,S'
    EXEC('SELECT id,name FROM sysobjects WHERE id IN('+@s+')')
    /*--结果:
    服务器: 消息 207,级别 16,状态 3,行 1
    列名 'S' 无效。
    服务器: 消息 207,级别 16,状态 1,行 1
    列名 'U' 无效。
    --*/
    GO--c. 忽略了比较的精确性问题。
    --要查询的数据
    DECLARE @t TABLE(col varchar(10))
    INSERT @t SELECT '1'
    UNION ALL SELECT '11'
    UNION ALL SELECT '111'
    UNION ALL SELECT '22'--查询
    DECLARE @s varchar(100)
    SET @s='111,22'
    SELECT * FROM @t WHERE CHARINDEX(col,@s)>0
    /*--结果
    col        
    ---------- 
    1
    11
    111
    22
    -*/
    GO
      

  4.   

    各位似乎没看清楚问题,我需要的不是SQL拼接,我需要的是拼接的游标
      

  5.   

    --1. 构造使用IN子句的动态Transact-SQL方法进行编号查询--a. 要查询的字段类型是数字型--查询的值列表
    DECLARE @idlist varchar(100)
    SET @idlist='1,2,3'--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
    GO--b. 要查询的字段类型是字符型
    --查询的值列表已经加上了字符串边界符
    DECLARE @idlist varchar(100)
    SET @idlist='''a'',''b''''a'',''c'''--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@idlist+')')
    GO--查询的值列表没有字符串边界符
    DECLARE @idlist varchar(100)
    SET @idlist='a,b''a,c'--由于是字段类型是,所以在拼接时,必须为其加上字符串边界符(')
    DECLARE @s varchar(1000)
    SET @s=''''
        +REPLACE(REPLACE(@idlist,'''',''''''),',',''',''')
        +''''--拼接并执行动态Transact-SQL语句
    EXEC('SELECT * FROM tbname WHERE fdname IN('+@s+')')
    GO/*=====================================================*/
    --2. 使用LIKE或者PATINDEX进行编号查询
    --查询的值列表
    DECLARE @idlist varchar(100)
    SET @idlist='1,2,3'--查询
    SELECT * FROM tbname WHERE CHARINDEX(','+RTRIM(fdname)+',',','+@idlist+',')>0
    SELECT * FROM tbname WHERE PATINDEX('%,'+RTRIM(fdname)+',%',','+@idlist+',')>0
    SELECT * FROM tbname WHERE ','+@idlist+',' LIKE '%,'+RTRIM(fdname)+',%'
    GO/*=====================================================*/
    --3. 编号查询中常见的错误
    --a. 最容易犯的错误:表达式充当表达式列表。
    DECLARE @s varchar(100)
    SET @s='1'
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    /*--结果
    id          name 
    ---------------- ------------
    1           sysobjects
    --*/SET @s='1,2,3'
    SELECT id,name FROM sysobjects WHERE id IN(@s)
    /*--结果
    服务器: 消息 245,级别 16,状态 1,行 3
    将 varchar 值 '1,2,3' 转换为数据类型为 int 的列时发生语法错误。
    --*/
    GO--b. 生成动态Transact-SQL语句时忽略了数据类型。
    DECLARE @s varchar(100)
    SET @s='U,S'
    EXEC('SELECT id,name FROM sysobjects WHERE id IN('+@s+')')
    /*--结果:
    服务器: 消息 207,级别 16,状态 3,行 1
    列名 'S' 无效。
    服务器: 消息 207,级别 16,状态 1,行 1
    列名 'U' 无效。
    --*/
    GO--c. 忽略了比较的精确性问题。
    --要查询的数据
    DECLARE @t TABLE(col varchar(10))
    INSERT @t SELECT '1'
    UNION ALL SELECT '11'
    UNION ALL SELECT '111'
    UNION ALL SELECT '22'--查询
    DECLARE @s varchar(100)
    SET @s='111,22'
    SELECT * FROM @t WHERE CHARINDEX(col,@s)>0
    /*--结果
    col        
    ---------- 
    1
    11
    111
    22
    -*/
    GO
      

  6.   

    我在4楼说了,如果拼接产生了一个查询返回集是不能直接把EXECUTE作为游标的查询结果的,
    定义游标后面只能跟SELECT查询语句;
    按你原先的方法返回值为空的,因为in内包含的是一个字符串而不是一串条件ID;
    我想的是拼接字符串产生的数据存入一个临时用表内然后查询该表作为游标的数据源;
    不知道有没有其他方法,呆呆初行者 哈哈哈.