sybase与oracle存储过程的写法对比

本文通过示例对比了Oracle与Sybase下创建存储过程的语法差异,展示了如何定义和使用游标、变量以及执行SQL语句等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在oracle中创建存储过程和sybase及sql server下的语法有些不一致之处。
下面就此用不同的数据库下存储过程的例子来演示之。
---------------------------
oracle下:
 

CREATE OR REPLACE FUNCTION MY_FUNC
(
P1 
IN MY_TABLE.YY%TYPE,
P2 
IN MY_TABLE.NN%TYPE,
P3 
VARCHAR(100)
)
RETURN VARCHAR2 AS
/*定义有参数的游标和无参数的游标*/
CURSOR MY_CURSOR1 IS
    
SELECT YY,NN,DECODE(FYYSDM,0,'合计',1,'加工费','其他费用要素')
    
FROM MY_TABLE
    
WHERE YY=P1
    
GROUP BY YY,NN
    
ORDER BY YY,NN;
/*定义游标变量,存储游标数据集中的记录*/
V_CURSOR1 MY_CURSOR1
%ROWTYPE; 

CURSOR MY_CURSOR2(V_ZYDM MY_TABLE.ZYDM%TYPE,V_FYYSDM NUMBERAS
    
SELECT YY,NN,ZYDM,NVL(ZYCB,0/*NVL函数转换空值为指定值*/
    
FROM MY_TABLE
    
WHERE YY=P1 AND NN=P2 AND ZYDM=V_ZYDM AND FYYSDM=V_FYYSDM
    
GROUP BY YY,NN;
/*定义游标变量,存储游标数据集中的记录*/
V_CURSOR2 MY_CURSOR2
%ROWTYPE; 

V_CPDM  MY_TABLE.CPDM
%TYPE;
V_COUNT 
NUMBER;
V_BZ    
VARCHAR2(2);
V_CPCB  
NUMBER(22,2);

BEGIN
    V_BZ:
=1;
    
SELECT CPDM INTO V_CPDM FROM MY_TABLE;
    
SELECT CPCB INTO V_CPCB FROM MY_TABLE WHERE ROWNUM=1;
    
    
IF MY_CURSOR1%ISOPEN THEN /*判断游标是否已经打开*/
        
CLOSE MY_CURSOR1;
    
END IF;
    
OPEN MY_CURSOR1;
    
FETCH MY_CURSOR1 INTO V_CURSOR1;
    
IF MY_CURSOR1%NOTFOUND THEN /*游标返回结果为空*/
        
CLOSE MY_CURSOR1;
           
RETURN(V_BZ);
    
END IF;
    
WHILE MY_CURSOR1%FOUND LOOP /*游标返回结果不为空*/
        V_CPDM:
=V_CURSOR1.CPDM;
        V_CPCB:
=V_CURSOR1.CPCB;
        V_COUNT:
=100;
        
IF V_COUNT=100 THEN
            V_COUNT:
=99;
        
END IF;
            
FETCH MY_CURSOR1 INTO V_CURSOR1;
    
END LOOP;
    
CLOSE MY_CURSOR1;

    
/*显式打开带参游标*/
    
SELECT CPDM INTO V_CPDM FROM MY_TABLE;
    
OPEN MY_CURSOR2;
    
FETCH MY_CURSOR2 INTO V_CURSOR2;
    
WHILE MY_CURSOR2%FOUND LOOP /*游标返回结果不为空*/
        V_CPDM:
=V_CURSOR2.CPDM;
        V_CPCB:
=V_CURSOR2.CPCB;
        V_COUNT:
=100;
        
IF V_COUNT=100 THEN
            V_COUNT:
=99;
        
ELSE
            V_COUNT:
=88;
        
END IF;
            
FETCH MY_CURSOR2 INTO V_CURSOR2;
    
END LOOP;
    
CLOSE MYCURSOR2;

    
/*隐式打开游标*/
    
FOR V_CURSOR2 IN MY_CURSOR2(V_CPDM,V_CURSOR1.FYYSDM) LOOP
        
IF V_CURSOR2.CPCB IS NULL THEN
           
PRINT '非法!';
           
ROLLBACK;
        
END IF;

        
UPDATE MY_TABLE
        
SET CPCB=V_CPCB
        
WHERE YY=P1 AND NN=P2 AND CPDM=V_CURSOR2.CPDM;
        
IF SQL%NOTFOUND THEN /*判断前句是否有执行结果*/
           
/*程序段*/
        
END IF;
    
END LOOP;
    
    V_BZ:
=MY_DELETE_CB(P_YY,P_NN);
    
IF V_BZ<>0 THEN
        
PRINT '失败!';
    
END IF;
    
FOR I INT 1..V_COUNT LOOP
        
/**/
    
END LOOP;

    
COMMIT;/*提交事务*/
    
RETURN(0);/*要有返回值*/
END MY_FUNC;

CREATE OR REPLACE PROCEDURE SP_MY 
(
P_YY 
IN MY_TABLE.YY%TYPE;
P_NN 
NUMBER;
)
IS

CURSOR MY_CURSOR IS
    
SELECT CPCB 
    
FROM MY_TABLE 
    
WHERE YY=P_YY AND NN=P_NN;

V_ZYCB 
NUMBER(22,2);

BEGIN
    
/**/
    
/*无返回值*/
END;


附oracle下函数:
NVL(AAA,BBB)  空值判断函数,AAA是待判断变量,BBB为为空时要替换值
DECODE(ID,P1,S1,P2,S2,S3) 条件判断函数,假如ID是P1则返回S1,假如ID是P2则返回S2,否则返回S3。
RPAD(AAA,COUNT,'0') 字符补空函数,在AAA变量后补零,共字符串长COUNT。
SUBSTR(AAA,M,N) 取子串函数,取AAA从第M个字符开始,取N个字符。
LENGTH(STR)  取字符长度。
LENGTHB(STR) 取字符字节长度。
TO_CHAR()
TO_NUMBER()类型转换函数
--------------------------------------------------
SYBASE下:

CREATE PROCEDURE PRO_MY
(
@P_YY CHAR(4),
@P_NN CHAR(2)='01',
@P_OUT VARCHAR(255)=NULL OUTPUT
)
AS
BEGIN
    
DECLARE @V_CPDM NUMERIC(9,0),
            
@V_CPCB NUMERIC(22,2),
            
@V_ID   INT,
            
@V_JE   FLOAT

    
DECLARE CUR_TEST CURSOR FOR
        
SELECT CPCB,JE
        
FROM TEST
        
WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM
    
FOR READ ONLY

    
SELECT @V_CPCB=CPCB 
    
FROM TEST 
    
WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM
    
IF @@ROWCOUNT=0
        
PRINT '未找到'
    
ELSE
            
PRINT '找到'

    
OPEN CUR_TEST
    
FETCH CUR_TEST INTO @V_CPCB,@V_JE
    
IF @@SQLSTATUS=2 --返回结果集为空
    IF @@SQLSTATUS=1 --游标执行出错
    BEGIN
        
RAISERROR 20000 --返回自定义错误号
        --RAISERROR 20000,'错误信息' --返回自定义错误号
        ROLLBACK
        
RETURN 10
    
END
    
WHILE @@SQLSTATUS=0 --结果集返回正常结果
    BEGIN
        
/*Exception*/
        
FETCH CUR_TEST INTO @V_CPCB,@V_JE
    
END
    
    
SELECT @V_ID=@V_ID+1

    
IF (@V_STR NOT LIKE "[0-9]")
        
SELECT @@V_ID=1

    
EXECUTE @V_ID=DELETE_CB @P_YY,@P_NN  

    
UPDATE TEST SET CPCB=100 WHERE YY=@P_YY AND NN=@P_NN
    
IF @@ERROR!=0
             
PRINT '更新失败'  

    
RETURN 0

END


附录:
CONVERT(INT,@V_JE) --类型转换函数
LTRIM(@V_STR) --去掉左空格
RTRIM(@V_STR) --去掉右空格
ROUND(@V_JE,2) --数值小数位数设定
SUBSTRING(@V_STR,M,N) --取子字符串
STR(@V_JE,M,N) --设置数值的显示位数和小数位数
CHAR_LENGTH(@V_STR) --字符串长度
PATINDEX("%[0-9]%",@V_STR) --取前边字符在后面字符串中的起始位置
patindex("%[kKmMgGpP]%", @v_str)
--case语句
CASE @V_ID WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE 'OTHER' END
ISNULL(@V_JE,0) --非空值判断
-------------------------
另外:
关于事务处理:
ORACLE下不用显式打开事务,直接提交即可,而且可以分步提交,多次提交,不用成对出现。
SYBASE必须显式打开和提交事务,且必须成对出现,平时我们单条更新语句的执行被sybase默认为隐式事务来提交。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值