Oracle SQL:如何读取和增加字段

Posted

技术标签:

【中文标题】Oracle SQL:如何读取和增加字段【英文标题】:Oracle SQL: How to read-and-increment a field 【发布时间】:2010-01-08 17:14:48 【问题描述】:

我正在重构企业应用程序的数据导入过程,遇到了一个 sn-p,我想找到一个更好的解决方案。导入数据时,我们必须为每个数据集创建一个唯一实体,并且在字段中有一个计数器用于按顺序分配此 ID。您读取该字段以获取下一个空闲 id,然后将其递增以准备下一次。

目前这是在原始应用程序中分两步完成的,用“C”编写:

   SELECT idnext FROM mytable;
   UPDATE mytable SET idnext = idnext + 1;

如果多个进程做同样的事情,这里显然存在竞争条件。

编辑:重要的附带条件:我无法触及数据库/字段定义,这排除了序列。

我们正在用 perl 重写,我想做同样的事情,但更好。原子解决方案会很好。不幸的是,我的 SQL 技能有限,所以我求助于集体智慧:-)

【问题讨论】:

感觉更新sql只够对了'UPDATE mytable SET idnext = idnext + 1;'为什么你需要阅读 idnext to server? 【参考方案1】:

在这种特殊情况下,如前所述,序列是正确的解决方案。但是,如果在未来的某些情况下,您需要在同一语句中更新某些内容并返回一个值,您可以使用 RETURNING 子句:

UPDATE atable SET foo = do_something_with(foo) RETURNING foo INTO ?

如果调用代码是 PL/SQL,请替换 ?使用本地 PL/SQL 变量;否则你可以将它绑定为程序中的输出参数。

编辑:既然你提到了 Perl,这样的东西应该可以工作(未经测试):

my $sth = $dbh->prepare('UPDATE mytable SET idnext = idnext + 1 returning idnext into ?');
my $idnext;
$sth->bind_param_inout(1, \$idnext, 8);
$sth->execute; # now $idnext should contain the value

见DBI。

【讨论】:

所以我的语句应该是这样的: (?) UPDATE mytable SET idnext = idnext + 1 RETURNING idnext; 我的调用代码是perl。我在 sql 命令行上试过这个,但它有语法问题: UPDATE mytable SET idnext = idnext + 1 RETURNING idnext INTO 部分是必需的。而且它不会在命令行上工作(据我所知)。 抱歉耽搁了,其他事情更紧急......这对我来说很好用,我必须减少 idnext 因为这个语句在增加后返回值,我需要它在增加之前.幸运的是,一个简单的 $idnext-- 解决了这个问题。谢谢!【参考方案2】:

为什么不使用sequence?

使用您想要的任何 START WITH 值创建一次序列:

CREATE SEQUENCE mysequence
  START WITH 1
  MAXVALUE 999999999999999999999999999
  MINVALUE 1
  NOCYCLE
  NOCACHE
  NOORDER;

然后在你的应用程序代码运行时你可以使用这个语句来获取下一个值:

SELECT mysequence.NEXTVAL
  INTO idnext
  FROM DUAL;

更新:使用序列将是首选方法,但由于您无法更改数据库,所以我同意使用 RETURNING 应该适用于您的情况:

   UPDATE mytable 
      SET idnext = idnext + 1 
RETURNING idnext 
     INTO mylocalvariable;

【讨论】:

我必须使用现有的字段,不能触摸它的定义。【参考方案3】:

使用 SELECT FOR UPDATE 语句。它保证对记录的互斥权:

"SELECT FOR UPDATE;

【讨论】:

你能提供一个完整的例子吗?【参考方案4】:

sequence 将完成这项工作,看看例如Oracle sequences

【讨论】:

以上是关于Oracle SQL:如何读取和增加字段的主要内容,如果未能解决你的问题,请参考以下文章

在sql数据库中,一个表中某一个字段有很多用,隔开的数据,请问用sql语句如何分别读取这个表中的每一个数据

JAVA读取Oracle数据库Clob字段转换成String问题

Java 存储和读取 oracle CLOB 类型字段的实用方法

oracle 10G数据库如何插入clob字段的值的简单语句sql语句

关于SQL触发器 B表读取A表的字段信息 并更新到指定的B表字段

SQL语句怎样进行数据库字段的条件查询?