MS Access 是否会抑制插入时的主键违规?

发布于 2024-11-30 05:53:10 字数 1035 浏览 0 评论 0原文

我正在将 MS Access 数据库重写为 SQL Server,并在 Access 中发现了一个奇怪的问题,我希望有人可以帮助解决。

我有一个表,我们将其称为“主”表,其中帐户上的主键已编入索引且不允许重复。看起来很简单,但我的问题是在插入数据时发生的。

我的 INSERT 查询是(为了简洁起见,字段数量受到限制)

INSERT INTO Main (Account, SentDate, Amount)
SELECT C.Account, C.SentDate, C.Amount
FROM 
    (CALLS C LEFT JOIN Bals B ON C.Account = B.ACCT_ID) 
LEFT JOIN AggAnt A ON C.Account = A.Account

问题是这样的,如果我运行查询的 SELECT 部分,我会得到 2365 条记录,但是当我运行 INSERT< /code> 我得到 2364 条记录。所以我做了一些检查,发现一个帐户重复,记录之间的差异是发送日期和金额。但 Access 仅插入一条记录,并且不会抛出任何类型的错误消息或任何内容。查询中没有任何内容表明选择最近的日期等。

示例数据:

Account    SentDate   Amount
12345678   8/1/2011   123.00
23456789   8/1/2011   45678.00
34567890   8/1/2011   7850.00
45678912   8/1/2011   635.00
45678912   5/1/2011   982.00
56789123   8/1/2011   2639.00

在示例中,当我运行 INSERT 时,我有一个重复的帐户 45678912,我没有收到任何错误,并且从 8/1/ 获取记录2011年。

当这违反了表上的 PK 时,为什么 Access 不会抛出错误? Access 中是否存在选择一条记录并跳过另一条记录的怪癖?

我完全被这个问题难住了,所以任何帮助都会很棒。

I am in the process of re-writing an MS Access database to SQL server and have found an strange issue in Access that I am hoping someone can help with.

I have a table let's call it 'Main' with a Primary Key on the Account that is indexed and doesn't allow for duplicates. Seems simple enough but my issue is occurring when data is getting Inserted.

My INSERT query is (the number of fields have been limited for brevity)

INSERT INTO Main (Account, SentDate, Amount)
SELECT C.Account, C.SentDate, C.Amount
FROM 
    (CALLS C LEFT JOIN Bals B ON C.Account = B.ACCT_ID) 
LEFT JOIN AggAnt A ON C.Account = A.Account

The issue is this, if I run the SELECT portion of my query I get 2365 records but when I run the INSERT I get 2364 records. So I did some checking and I found one Account is duplicated the difference between the records is the SentDate and the Amount. But Access is inserting only one of the records and not throwing any kind of error message or anything. There is nothing in the query that says select the most recent date, etc.

Sample Data:

Account    SentDate   Amount
12345678   8/1/2011   123.00
23456789   8/1/2011   45678.00
34567890   8/1/2011   7850.00
45678912   8/1/2011   635.00
45678912   5/1/2011   982.00
56789123   8/1/2011   2639.00

In the sample I have one account that is duplicated 45678912 when I run my INSERT, I get no errors and I get the record from 8/1/2011.

Why is Access not throwing an error when this violates the PK on the table? Is there some quirk in Access to select one record and just skip the other?

I am totally stumped by this issue so any help would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扛起拖把扫天下 2024-12-07 05:53:10

您如何运行查询?如果您使用的是 DoCmd.RunSQL,请切换到使用 DAO 数据库对象的 .Execute 方法,并使用 dbFailOnError

Dim db As DAO.Database
Dim strInsert As String
strInsert = "your insert statement"
Set db = CurrentDb
db.Execute strInsert, dbFailOnError
Set db = Nothing

编辑:如果 Main 是指向 SQL Server 表的 ODBC 链接,我将检查 db.Execute strInsert、dbFailOnError 之后的错误收集 (DAO)

How are you running the query? If you're using DoCmd.RunSQL, switch to using the .Execute method of a DAO database object, and use dbFailOnError.

Dim db As DAO.Database
Dim strInsert As String
strInsert = "your insert statement"
Set db = CurrentDb
db.Execute strInsert, dbFailOnError
Set db = Nothing

Edit: If Main is an ODBC link to a SQL Server table, I would examine the Errors Collection (DAO) after db.Execute strInsert, dbFailOnError

我是男神闪亮亮 2024-12-07 05:53:10

在 HansUp 指示我检查 SetWarnings = false 的方向之后。我发现它埋在我的代码中,这就是为什么没有关于由于主键违规而未插入记录的警告消息。

需要注意的是,请确保您希望抑制这些消息。

After HansUp pointing me in the direction of checking for SetWarnings = false. I found it buried in my code which is why there was no warning message about the records not being inserted due to primary key violations.

A word of caution would be to make sure you want these messages suppressed.

笨死的猪 2024-12-07 05:53:10

访问[更新]一条记录时是否有一些怪癖,只需跳过
其他?

是的,您可以在引擎级别控制此行为(如果使用 OLE DB,也可以在记录集级别)。

对于 OLE DB(例如 ADO),设置为 Jet OLEDB:Global Partial Bulk Ops< /代码>

确定 Jet 数据库引擎在 SQL DML 批量处理时的行为
操作失败。当设置为允许部分完成批量时
操作时,可能会发生不一致的更改,因为对某些操作
记录可能会成功,而其他记录可能会失败。当设置为不允许时
部分完成批量操作,如果出现以下情况,则回滚所有更改
发生单个错误。 Jet OLEDB:全球部分批量操作
属性设置可以在每个记录集的基础上被覆盖
设置 Jet OLEDB:Partial Bulk Ops 属性
Recordset 对象的Properties 集合。

请注意,默认情况下不允许部分完成批量操作。

Is there some quirk in Access to [update] one record and just skip the
other?

Yes, you can control this behaviour at the engine level (also at the recordset level if using OLE DB).

For OLE DB (e.g. ADO) the setting is Jet OLEDB:Global Partial Bulk Ops:

determines the behavior of the Jet database engine when SQL DML bulk
operations fail. When set to allow partial completion of bulk
operations, inconsistent changes can occur because operations on some
records could succeed and others could fail. When set to allow no
partial completion of bulk operations, all changes are rolled back if
a single error occurs. The Jet OLEDB:Global Partial Bulk Ops
property setting can be overridden on a per-Recordset basis by
setting the Jet OLEDB:Partial Bulk Ops property in the
Properties collection of a Recordset object.

Note the default is to allow no partial completion of bulk operations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文