什么表A中插入信息,并使用该指数从表A中的涉及到表B.最好的办法最好的方法,使双插入
的“解决方案”我试图在插入表A的信息(其中有一个自动生成的ID),那么,选择的最后一个索引,并在表B.插入这可能不是非常有用,因为最后一个索引可在插入物之间改变,因为另一个用户可以生成表A
一个新的索引我有这个问题与各种DBMS postgreSQL,Informix,MySQL和MSSQL(感谢lomaxx的答案)
什么表A中插入信息,并使用该指数从表A中的涉及到表B.最好的办法最好的方法,使双插入
的“解决方案”我试图在插入表A的信息(其中有一个自动生成的ID),那么,选择的最后一个索引,并在表B.插入这可能不是非常有用,因为最后一个索引可在插入物之间改变,因为另一个用户可以生成表A
一个新的索引我有这个问题与各种DBMS postgreSQL,Informix,MySQL和MSSQL(感谢lomaxx的答案)
如果哟您可以使用MSSQL使用SCOPE_IDENTITY返回当前会话中插入的最后一个ID。然后你可以用它来插入表B.
This article from MSDN给出了一个体面的例子,说明如何做到这一点。
这是序列解决方案(对于postgres),当然你必须在存储过程或应用程序代码中执行。
postgres=# create table foo(id serial primary key, text varchar);
NOTICE: CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
postgres=# create table bar(id int references foo, text varchar);
CREATE TABLE
postgres=# select nextval('foo_id_seq');
nextval
---------
1
(1 row)
postgres=# insert into foo values (1,'a'); insert into bar values(1,'b');
INSERT 0 1
INSERT 0 1
对于MySQL,交易重要的是不要自己的脚绊倒的情况下,你使用一个以上的插入相同的连接。
对于LAST_INSERT_ID(),最 最近生成的ID被保持在 服务器上的每个连接的基础。 它不会被另一个客户端更改。 如果更新 另一个具有 非魔术值的AUTO_INCREMENT列(即 不为NULL且不为0的值),它甚至不会更改。 列同时使用 LAST_INSERT_ID()和AUTO_INCREMENT从多个 客户是完全有效的。每个 客户端将收到最后插入 ID为客户 执行的最后一条语句。
mysql> create table foo(id int primary key auto_increment, text varchar(10)) Engine=InnoDB;
Query OK, 0 rows affected (0.06 sec)
mysql> create table bar(id int references foo, text varchar(10)) Engine=InnoDB;
Query OK, 0 rows affected (0.01 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into foo(text) values ('x');
Query OK, 1 row affected (0.00 sec)
mysql> insert into bar values (last_insert_id(),'y');
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.04 sec)
使用IBM Informix Dynamic Server(IDS),它取决于您用于实现双重插入的语言。如果它是服务器(SPL - 存储过程语言),并且如果您使用的是SERIAL列,那么在插入表B时使用DBINFO('sqlca.sqlerrd2')来表示添加到表A的序列值。如果您在客户端(ESQL/C,I4GL,JDBC,ODBC)的工作,则经由接口批准收集串行(sqlca.sqlerrd [1]在ESQL/C,sqlca.sqlerrd [2] I4GL),然后将其传送再次回来。
IDS还支持序列号,以便您可以使用该技术来代替。
IDS 11.50支持SERIAL8和BIGSERIAL以及SERIAL(一个4字节整数);每个细节的接口略有不同,但基本原理是一样的。
如果你的表是UUID键控,产生UUID和两个插入使用。
在Microsoft Knowledge Base中描述了Access 2000+(Jet 4.0)答案。基本上,您可以使用SELECT @@Identity
来检索连接上生成的自动增量字段的值。
另一接入2000+(喷气4.0)的答案是创建一个Jet 4.0 VIEW
(在Access术语:一个SELECT
查询保存为查询对象)与上IDENTITY
(自动编号)柱的INNER JOIN
;连接列必须显示在SELECT子句和引用的表中。然后INSERT INTO
VIEW
为没有DEFAULT
的所有NOT NULL
列提供值。
可以省略IDENTITY
列值,在这种情况下,引擎将像往常一样自动生成值,或提供并确认显式值;如果另外提供了另一个表(没有IDENTITY
列的连接列)的值,则它必须与IDENTITY
的值相同,否则会发生错误;如果省略IDENTITY
值,则为连接列提供的任何值都将被忽略。请注意,FOREIGN KEY
通常会在这些表格之间预期,但不是此过程起作用的先决条件。
快速示例(ANSI-92查询模式的Jet 4.0语法):
CREATE TABLE Table1
(
key_col INTEGER IDENTITY NOT NULL PRIMARY KEY,
data_col_1 INTEGER NOT NULL
)
;
CREATE TABLE Table2
(
key_col INTEGER NOT NULL,
data_col_2 INTEGER NOT NULL,
PRIMARY KEY (key_col, data_col_2)
)
;
CREATE VIEW View1
AS
SELECT T1.key_col AS key_col_1, T2.key_col AS key_col_2,
T1.data_col_1, T2.data_col_2
FROM Table2 AS T2
INNER JOIN Table1 AS T1
ON T1.key_col = T2.key_col
;
INSERT INTO View1 (data_col_1, data_col_2)
VALUES (1, 2)
;
如果您使用2005+也可以使用其输出已被更新的数据OUTPUT子句SQL服务器,插入或删除。这非常酷,正是你需要它的东西的类型。 http://msdn.microsoft.com/en-us/library/ms177564.aspx
在SQL Server中,您使用@@ IDENTITY字段,并且还将INSERT
包装在事务中。
DEFINE ... etc etc
BEGIN TRANSACTION
INSERT INTO table1 (value1) VALUES (@p_value1)
SET @pk_table1 = @@IDENTITY
INSERT INTO table2 (pk_table1, value2) VALUES (@pk_table1, @p_value2)
COMMIT
它在TSQL最佳实践的@@IDENTITY
价值INSERT
后立刻存储在一个变量,以避免日后的维护代码被损坏的价值。
这也是使用存储过程的最佳实践。
在Oracle中,使用序列保持PK值,并用返回的条款
INSERT INTO table1 (pk_table1, value1)
VALUES (table1_seq.NEXTVAL, p_value1) RETURNING pk_table1 INTO l_table1_id;
INSERT INTO table2 (pk_table2, pk_table1, value2)
VALUES (table2_seq.NEXTVAL, l_table1_id, p_value2);
它使用包装的Oracle存储所有的SQL /数据操作的appilcation层的最佳实践。
如果它在Informix和JSP中,有一个函数在插入后返回表的Serial字段。
import com.informix.jdbc.*;
cmd = "insert into serialTable(i) values (100)";
stmt.executeUpdate(cmd);
System.out.println(cmd+"...okay");
int serialValue = ((IfmxStatement)stmt).getSerial();
System.out.println("serial value: " + serialValue);
(出于某种原因,在我的工作电脑它描述了在西班牙的一切,也许是因为在墨西哥)
使用事务来避免这个问题:“这可能不是很因为最后一个索引可能会在插入之间发生变化,因为另一个用户可能会在表A中生成一个新的索引。“
而且,在PostgreSQL里,你可以使用‘NEXTVAL’和‘使用currval’来完成你想做的事:
BEGIN;
INSERT INTO products (prod_id, prod_name, description) VALUES (
nextval('products_prod_id_seq')
, 'a product'
, 'a product description'
);
INSERT INTO prices (price_id, prod_id, price) VALUES (
nextval('prices_price_id_seq')
, currval('products_prod_id_seq')
, 0.99
);
COMMIT;
让我知道如果你需要一个DDL片段以及
我认为你的问题可能会更清楚一些,'表A'的索引并不自动意味着“自动生成的值”,这是我认为你所指的。'最后一个索引'在有很多并发时是不可靠的 – 2008-09-30 06:12:17
感谢您的帮助,我会让它更清晰 – seFausto 2008-09-30 06:22:36
有编辑权限的人可以解决这个问题的索引问题吗? – Vidar 2009-01-21 18:04:04