日期:2014-05-17  浏览次数:20443 次

存储过程返回游标 怎么用
CREATE PROCEDURE dbo.uspCurrencyCursor 
  @CurrencyCursor CURSOR VARYING OUTPUT
AS
  SET NOCOUNT ON;
  SET @CurrencyCursor = CURSOR
  FORWARD_ONLY STATIC FOR
  SELECT
uid
,name
  FROM dbo.sysusers
  OPEN @CurrencyCursor;

create PROC CALLCURSOR
AS

DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN
  FETCH NEXT FROM @MyCursor;
END
CLOSE @MyCursor;
DEALLOCATE @MyCursor;

自己根据网上的例子,写的,不是很明白啊
存储过程 返回变量,结果集 这个经常用;返回游标,我真没有用过,什么情况下适合用呢,怎么用?
用过的给说说呗,最好能给个demo,谢谢了


------解决方案--------------------
SQL code
例如:一个公司,按照如下规则计算加薪金额:
 1.公司中除了总裁(president)外,所有人都会至少增加p_min的薪水
 2.任何奖金(bonus)高于$600的员工都会另增加4%
 3.员工的佣金(commission)越高,增加越少。佣金(commission)少于$2000的另增加3%,佣金(commission)在$2000到$3000的增加另2%
 4.佣金(commission)高于$3000的另增加1%
 5.无论每个员工增加多少,增加比例不能高于p_max
CREATE PROCEDURE total_raise ( IN  p_min DEC(4,2)
                                           , IN  p_max DEC(4,2)
                                           , OUT p_total DEC(9,2) )
    LANGUAGE SQL
    SPECIFIC total_raise      
tr: BEGIN
    -- Declare variables
    DECLARE v_salary DEC(9,2);
    DECLARE v_bonus  DEC(9,2);
    DECLARE v_comm   DEC(9,2);
    DECLARE v_raise  DEC(4,2);
    DECLARE v_job    VARCHAR(15) DEFAULT 'PRES';
    -- Declare returncode
    DECLARE SQLSTATE CHAR(5);

    -- Procedure logic
    DECLARE c_emp CURSOR FOR
        SELECT salary, bonus, comm
        FROM   employee
        WHERE  job != v_job;                              -- (1)这里的SELECT定义了结果集中的行和
                                                                          列
        OPEN c_emp;                                        -- (2)
 
        SET p_total = 0;
        FETCH FROM c_emp INTO v_salary, v_bonus, v_comm;  -- (3)得到一行数据,并将其
                                                                                           复制给本地变量
 
        WHILE ( SQLSTATE = '00000' ) DO                   --SQLSTATE 00000: 操作执行成功,
                                                                            并且未产生任何类型的警告或异常情
                                                                            况。通过这个可以检查是否到达最后一行
           SET v_raise = p_min;
           IF ( v_bonus >= 600 ) THEN
               SET v_raise = v_raise + 0.04;
           END IF;

           IF ( v_comm < 2000 ) THEN
               SET v_raise = v_raise + 0.03;
           ELSEIF ( v_comm < 3000 ) THEN
               SET v_raise = v_raise + 0.02;
           ELSE
               SET v_raise = v_raise + 0.01;
           END IF;

           IF ( v_raise > p_max ) THEN
               SET v_raise = p_max;
           END IF;

           SET p_total = p_total + v_salary * v_raise;
           FETCH FROM c_emp INTO v_salary, v_bonus, v_comm;  -- (4)在WHILE逻辑中得到
                                                                                              更多的行数据
       END WHILE;

       CLOSE c_emp;                                          -- (5)
   END tr
    如果只是想把结果集中的第一个值复制给本地变量,而声明一个游标是不恰当的,因为打开游标会耗费很多资源。所以如下这段代码:
DECLARE c_tmp CURSOR FOR
        SELECT c1
        FROM t1;
OPEN c_emp;
FETCH FROM c_emp INTO v_c1;
CLOSE c_emp;
应当用有FETCH FIRST 1 ROW ONLY的子句的SQL语句:SELECT c1 INTO v_c1 FROM t1 FETCH FIRST 1 ROW ONLY;

------解决方案--------------------
SQL code

--示例:
create table 同学表(   
学号 varchar(6) primary key,   
姓名 varchar(8) not null,   
性别 varchar(2) default '男',   
出生日期 datetime,   
年龄 int,   
身份证号 varchar(18) unique,   
宿舍编号 varchar (3) )  
go   
insert 同学表 values('061201','张三','女','1988-11-23',20,'421022198811233025','001')   
insert 同学表 values('061202','李四','男','1987-1-12',21,'421022198701123025','001')   

create table 班主任表(   
学号 varchar(6) primary key,