【发布时间】:2013-12-25 23:18:54
【问题描述】:
对不起,如果问题标题有误导性或不够准确,但我没有看到如何用一句话问。
假设我们有一个表,其中 PK 是一个字符串(数字从 '100,000' 到 '999,999',逗号仅供阅读)。 也可以说,PK不是按顺序使用的。
现在我想使用 java.sql 在表中插入一个新行,并向用户显示插入行的 PK。由于默认情况下不生成 PK(例如,没有 PK 的插入值不起作用,在给定的环境中像 generate_keys 这样的东西不可用)我看到了两种不同的方法:
在两个不同的语句中,首先找到一个可能的下一个键,然后尝试插入(并期望另一个事务在两个语句之间的时间内使用相同的键) - 重试直到成功是否有效或任何 sql 技巧这里有事务设置/锁定帮助吗?我如何在 java.sql 中实现这一点?
对我来说,这是一个令人失望的解决方案,因为不确定的行为(也许你可以说服我相反),所以我搜索了另一个:
使用查找下一个可能的 PK 的嵌套选择语句插入。查找有关自己生成 PK 的其他答案我接近于使用该语句的工作解决方案(省略了从字符串到 int 的强制转换):
INSERT INTO mytable (pk,othercolumns)
VALUES(
(SELECT MIN(empty_numbers.empty_number)
FROM (SELECT t1.pk + 1 as empty_number
FROM mytable t1
LEFT OUTER JOIN mytable t2
ON t1.pk + 1 = t2.pk
WHERE t2.pk IS NULL
AND t1.pk > 100000)
as empty_numbers),
othervalues);
这就像一个魅力,并且(afaik)比我的第一种方法更可预测和稳定的解决方案,但是:我怎么可能从该语句中检索生成的 PK?我读过没有办法直接返回插入的行(或任何列),而且我发现的大多数谷歌结果都指向返回生成的密钥——即使我的密钥是生成的,它也不是由 DBMS 生成的直接,但根据我的声明。
注意,开发中使用的 DBMS 是 MSSQL 2008,而生产系统目前是 AS/400 上的 DB2(不知道哪个版本),所以我必须遵守 SQL 标准。我无法以任何方式更改数据库结构(例如,使用生成的密钥,我不确定存储过程)。
【问题讨论】:
-
查看
OUTPUTclause(我认为这是特定于 SQL Server)。 -
是的,但是 sql server 的细节是不可能的 :-(
-
为什么不使用将在生产中使用的相同数据库系统进行开发? (顺便说一句,从技术上讲,由于 IBM 自 2000 年以来就没有发布过 AS/400,所以几乎可以肯定您使用的是更新的 iSeries 或 Power System。操作系统的当前版本称为 IBM i 7.1。)您的 DB2 系统管理员(或“安全官”)应该能够轻松地为您创建一个测试模式(“库”),如果您自己不能这样做的话。为什么您的 PK 值是数字的字符串表示形式?您是否保证只有一个用户进程连接到您的数据库,可以将行插入此表?
-
@WarrenT 你的观点是正确的(是的,它是 iSeries 上的 DB2),但不幸的是,我对生产系统没有影响,范围内没有真正的数据库管理员或安全官员,唯一的我们的直接客户提供的测试数据是 mssql 备份,我知道至少有 5 个应用程序使用该表,恕我直言,字符串表示是某种我无法改变的历史错误(该项目中甚至发生了更奇怪的事情尤其是那个分贝,我只是不想为此生气)
标签: java sql sql-server db2 ibm-midrange