我需要插入访问数据库。但如果表中已有列dup,则跳过该行。
到目前为止我所拥有的是:
<cfoutput query="hours">
<cfquery name="Employee" datasource="test">
INSERT INTO Tbl_Hours_Comments
(ID, ship_num, dup)
values(#hours.id#, #hours.ship#, #hours.dup#)
</cfquery>
</cfoutput>
如果我不复制主键。然后它将INSERT重复。如果我复制一个主键。然后我收到了一个错误。
我想我需要像MySQL这样的东西。在DUPLICATE KEY UPDATE。
或者也许像Oracle中的dup_val_on_index异常处理。
@Gord Thompson
我试过了(不确定我是否正确行事):
<cfoutput query="hours">
<cfquery name="Insert_Employee" datasource="trung">
INSERT Tbl_Hours_Comments (ID, ship_num, dup)
values(#hours.id#, #hours.ship#, #hours.dup#)
SELECT ? as dup
FROM( SELECT COUNT(*) as n from Tbl_Hours_Comments) as Dual
WHERE NOT EXISTS
( SELECT *
FROM Tbl_Hours_Comments
WHERE dup = ?
)
</cfquery>
</cfoutput>
但是我的[Microsoft] [ODBC Microsoft Access Driver] COUNT字段不正确。
是什么?在你的选择声明?
答案 0 :(得分:3)
如果您使用Microsoft Access ODBC驱动程序更新数据库,则可以使用INSERT ... SELECT ... WHERE NOT EXISTS
。以下示例在Python中,但看起来您应该能够在ColdFusion中执行类似的操作。
import pyodbc
cnxn = pyodbc.connect("DSN=db1") # Microsoft Access ODBC
crsr = cnxn.cursor()
hours_ship = "ship102" # test data
hours_dup = 3 #
sql = """\
INSERT INTO Tbl_Hours_Comments (ship_num, dup)
SELECT ? as ship_num, ? AS dup
FROM (SELECT COUNT(*) AS n FROM Tbl_Hours_Comments) AS Dual
WHERE NOT EXISTS (SELECT * FROM Tbl_Hours_Comments WHERE dup = ?)
"""
params = (hours_ship, hours_dup, hours_dup)
crsr.execute(sql, params)
cnxn.commit()
print("{} row(s) inserted".format(crsr.rowcount))
crsr.close()
cnxn.close()
请注意,此方法不使用Microsoft Access OLEDB提供程序。
答案 1 :(得分:3)
<强>更新强>
如果由于某种原因您无法直接查询外部数据库,请尝试使用Gord Thompson's suggestion上的变体。它不像INSERT / SELECT .. FROM Table那样有效,但是......将适用于MS Access。
INSERT INTO Tbl_Hours_Comments (ID, ship_num, dup)
SELECT <cfqueryparam value="#hours.id#" cfsqltype="(your column type here)">
, <cfqueryparam value="#hours.ship#" cfsqltype="(your column type here)">
, <cfqueryparam value="#hours.dup#" cfsqltype="(your column type here)">
WHERE NOT EXISTS
(
SELECT NULL
FROM Tbl_Hours_Comments dupe
WHERE dupe.id = <cfqueryparam value="#hours.id#" cfsqltype="(your column type here)">
AND dupe.ship = <cfqueryparam value="#hours.ship#" cfsqltype="(your column type here)">
AND dupe.dup = <cfqueryparam value="#hours.dup#" cfsqltype="(your column type here)">
)
“小时”查询中的数据来源是什么? MS Access支持使用IN子句直接查询某些external databases(MS Access,SQL Server,Excel,ecetera)。例如:
SELECT Column1, Column2
FROM TableName IN 'c:\path\to\external.mdb'
因此,如果数据来自(支持的)外部数据库或同一数据库中的另一个表,则跳过cfloop
并运行单个 INSERT INTO会更有效率/ SELECT查询。只需将它与OUTER JOIN或NOT EXISTS子句组合,即可排除目标表中已存在的记录。
免责声明 - 我很久没有使用过Access,但语法应该是这样的:
选项#1 - 外部加入
INSERT INTO Tbl_Hours_Comments (ID, ship_num, dup)
SELECT ex.id, ex.ship, ex.dup
FROM OtherTable ex LEFT JOIN Tbl_Hours_Comments dupe
ON dupe.id = ex.id
AND dupe.ship = ex.ship
AND dupe.dup = ex.dup
WHERE dupe.id IS NULL
选项#2 - 不存在
INSERT INTO Tbl_Hours_Comments (ID, ship_num, dup)
SELECT ex.id, ex.ship, ex.dup
FROM OtherTable ex
WHERE NOT EXISTS
(
SELECT NULL
FROM Tbl_Hours_Comments dupe
WHERE dupe.id = ex.id
AND dupe.ship = ex.ship
AND dupe.dup = ex.dup
)
答案 2 :(得分:0)
我想发布我最终做的事情,以防有人帮助。
感谢@Leigh和@Gord提供有关此问题的帮助。
这就是我最终解决它的问题。它与Leigh和Gord的子查询方式非常相似。
I CFQUERY两个表(QueryA和QueryB)。
然后我使用了这个(来自https://coldfusionblog.wordpress.com/2012/01/11/how-to-do-an-outer-join-in-query-of-queries/):
<cfquery name="unique">
SELECT *
FROM QueryA
WHERE QueryA.ID NOT IN (#ValueList(QueryB.ID)#)
</cfquery>
获取QueryA中不在QueryB中的元素列表。
然后我使用另一个插入查询将所有新的唯一元素插入到QueryB中。