存储过程PR_READLOG_ADD
作用:往表 TB_MESSAGE_READLOG插入记录。
表TB_MESSAGE_READLOG 结构:
1) ID int
2)MessageId int
3)UserId int
4)ReadTime date
总共4个字段
存储过程语句:
/* Formatted on 2014/9/16 15:26:01 (QP5 v5.227.12220.39754) */
CREATE OR REPLACE PROCEDURE DEMO.PR_READLOG_ADD (
vUserId IN INT,
vMessageId IN INT,
oResInt OUT INT,
oResStr OUT VARCHAR2)
IS
i INT;
j INT;
/******************************************************************************
NAME: PR_READLOG_ADD
PURPOSE:
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 2014/9/16 Administrator 1. Created this procedure.
NOTES:
Automatically available Auto Replace Keywords:
Object Name: PR_READLOG_ADD
Sysdate: 2014/9/16
Date and Time: 2014/9/16, 15:11:24, and 2014/9/16 15:11:24
Username: Administrator (set in TOAD Options, Procedure Editor)
Table Name: (set in the "New PL/SQL Object" dialog)
******************************************************************************/
BEGIN
IF NVL (vUserId, 0) = 0 OR NVL (vMessageId, 0) = 0 THEN
oResInt := 0;
oResStr := '传入参数不正确!';
ELSE
SELECT COUNT (1)
INTO i
FROM tb_message
WHERE id = vMessageId;
SELECT COUNT (1)
INTO j
FROM tb_message_readlog
WHERE messageid = vMessageId AND userid = vUserId;
IF i = 0 OR j = 0 THEN
oResInt := 0;
oResStr := '记录不存在';
ELSE
INSERT INTO tb_message_readlog (id,
messageid,
userid,
readtime)
VALUES (fn_gen_getid ('tb_readlog'),
vMessageId,
vUserId,
SYSDATE);
COMMIT;
oResInt := 1;
oResStr := '创建成功';
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
oResInt := 0;
oResStr := '系统异常,请重试!';
RAISE;
END PR_READLOG_ADD;
/
存在问题
1)以上每次只能插入一条记录,要求能批量插入,传入 vUserId INT,vMessageIds varchar2。
vMessageIds 的 值是使用逗号分隔的数字,格式 ^\d+(,\d+)*$ 。
原理是先分隔 vMessageIds 再循环插入, 如何才可以实现?
/* Formatted on 2014/9/16 15:34:47 (QP5 v5.227.12220.39754) */
CREATE OR REPLACE PROCEDURE DEMO.PR_READLOG_ADD (
vUserId IN INT,
vMessageIds IN VARCHAR2,
oResInt OUT INT,
oResStr OUT VARCHAR2)
IS
i INT;
j INT;
BEGIN
oResInt := 0;
oResStr := "";
--1 使用程序分割 vMessageIds
--2 循环检测再插入
--3
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
oResInt := 0;
oResStr := '系统异常,请重试!';
RAISE;
END PR_READLOG_ADD;
/
------解决思路----------------------
BEGIN
IF NVL (vUserId, 0) = 0 OR NVL (vMessageId, 0) = 0 THEN
oResInt := 0;
oResStr := '传入参数不正确!';
ELSE
SELECT COUNT (1)
INTO i
FROM tb_message
WHERE id = vMessageId;
IF i = 0 THEN
oResInt := 0;
oResStr := '记录不存在';
ELSE
INSERT INTO tb_message_readlog (id,messageid,userid,readtime)
SELECT id,messageid,userid,readtime
FROM(select fn_gen_getid ('tb_readlog') ID,
REGEXP_SUBSTR(vMessageId, '[^,]+', 1, LEVEL) MessageId ,
vUserId USERID,
SYSDATE READTIME
from dual
CONNECT BY LEVEL <= length(vMessageId)-length(replace(vMessageId, ',','')) + 1) A
WHERE EXISTS (SELECT 1
FROM tb_message_readlog
WHERE messageid = A.MessageId AND userid = A.UserId);
COMMIT;
oResInt := 1;
oResStr := '创建成功';
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
oResInt := 0;
oResStr := '系统异常,请重试!';
RAISE;
END PR_READLOG_ADD;
------解决思路----------------------
oracle没有自带split的。
自定义split,可以使用管道函数实现。你百度下就知道了。
------解决思路----------------------
自定义split函数;
CREATE OR REPLACE TYPE split_type IS TABLE OF VARCHAR2 (100);
CREATE OR REPLACE FUNCTION split (
p_str IN VARCHAR2,
p_delimiter IN VARCHAR2 default(',') --分隔符,默认逗号
)
RETURN split_type
IS
j INT := 0;
i INT := 1;
len INT := 0;
len1 INT := 0;
str VARCHAR2 (4000);
my_split split_type := split_type ();
BEGIN
len := LENGTH (p_str);
len1 := LENGTH (p_delimiter);
WHILE j < len
LOOP
j := INSTR (p_str, p_delimiter, i);
IF j = 0
THEN
j := len;
str := SUBSTR (p_str, i);
my_split.EXTEND;
my_split (my_split.COUNT) := str;
IF i >= len
THEN
EXIT;
END IF;
ELSE
str := SUBSTR (p_str, i, j - i);
i := j + len1;
my_split.EXTEND;
my_split (my_split.COUNT) := str;
END IF;
END LOOP;
RETURN my_split;
END split;