【发布时间】:2018-03-23 17:47:33
【问题描述】:
有人告诉我,以下代码无法帮助我检查重复性,因为在 SELECT 和 UPDATE 语句之前结果可能不同。
PROCEDURE AddNew(Pname VARCHAR2, Pcountry VARCHAR2)
AS
already_exists BOOLEAN;
BEGIN
SELECT COUNT(*)>0 INTO already_exists FROM Publishers WHERE name=Pname;
IF already_exists THEN
RAISE_APPLICATION_ERROR(-20014,'Publisher already exists!');
END IF;
INSERT INTO Publishers(id,name,country)
VALUES (NewPublisherId(),Pname,Pcountry);
END;
这篇文章声称 SELECT 启动了一个事务: Why do I get an open transaction when just selecting from a database View?
这部分documentation 另有建议:
交易隐含地从任何获得 TX 的操作开始 锁:
发出修改数据的语句时
当发出 SELECT ... FOR UPDATE 语句时
使用 SET TRANSACTION 语句或 DBMS_TRANSACTION 包显式启动事务时
所以? SELECT 是否启动事务?
【问题讨论】:
-
过程的参数不能由 VARCHAR2 定义,其长度与使用 VARCHAR2(40) 或 (30) 的语句中的长度相同。
SELECT COUNT(*)>0 INTO不允许... -
如果您阅读了您链接的完整帖子,而不仅仅是接受的答案,您会看到
SELECT语句不会启动事务。 -
顺便问一下,您是在询问
SELECT是否启动了事务,还是在寻求有关存储过程的帮助?我不清楚。 -
无论如何,我肯定看到表格在
SELECT和INSERT之间得到更新,无论文档可能会或可能不会说什么。以这种方式编写存储过程绝对不是一个好习惯。 -
这就是 Nature 给我们 UNIQUE 约束的原因,以便我们可以在多用户环境中强制执行不重复值。
标签: sql oracle plsql transactions