任何使用 SQL View with two tables 编辑 MS-Access 表单数据的方法
Any way to edit data on MS-Access form using SQL View with two tables
根据我的阅读,如果被修改的数据仅表示一个 table 并且数据中包含一个唯一标识符字段,则应该可以编辑视图描述的数据。
根据微软
Any modifications must reference columns from only one base table
当底层记录集基于合并来自两个 table 的数据的视图或存储过程时,是否有人幸运地创建了 editable 的 MS-Access 表单?
我的表单只使用辅助 table 加入代码 table 以获得基于文本的描述 - 但这样做会使表单成为 uneditable.
我是否需要将其提取出来并为表单创建额外的查找代码?或者是否有人可以向我指出适合他们的示例?
这是我尝试用于编辑的表单的视图现在的样子 PreliminaryInvoices
table
SELECT t1.*, t2.JobTypeGroup AS Grouping
FROM dbo.PreliminaryInvoices AS t1
INNER JOIN dbo.tblJobTypes AS t2
ON t1.JobTypeID = t2.JobTypeID
编辑 - 更新以显示当前工作解决方案 - 没有第二个 table
我能够让它工作的唯一方法是拆分第二个 table 并添加一个查找以显示来自 JobTypeID
的文本
当前 Editable 查看:
SELECT t1.*
FROM dbo.PreliminaryInvoices AS t1
查找程序:
CREATE PROCEDURE [dbo].[spJobTypeGrouping]
-- Add the parameters for the stored procedure here
@TypeID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT dbo.tblJobTypes.[Grouping]
FROM dbo.tblJobTypes
WHERE dbo.tblJobTypes.JobTypeiD = @TypeID
END
如果您想更新无法从 Microsoft Access 中完全更新的视图,我建议您使用 SQL 服务器中的触发器来执行更新。
您可以定义一个 INSTEAD OF UPDATE
触发器来覆盖默认更新行为。
您可以在 MSDN 上阅读有关 INSTEAD OF
触发器的信息。这些允许您准确指定更新字段时发生的情况,甚至允许您更新计算列(例如,更改计算年龄列时更改某人的生日)。
要使用 T-SQL 查询和可更新视图,您需要将表单绑定到 ADO 记录集。您可以使用类似于以下代码的代码:
Private Sub Form_Load()
Dim conn As ADODB.Connection
'Open a valid connection here. I recommend a reusable function or class for opening connections
Dim rs As ADODB.Recordset
Set rs = conn.Open("SELECT * FROM dbo.MyView")
Set Me.Recorset = rs
End Sub
您应该在视图上创建 instead of
触发器,以便更新基础 table。您不必更新触发器中的所有字段。如果您创建了适当的触发器,Access 会将其视为 table。
至于您的触发器未涵盖的字段。如果用户尝试更新 table,UI 将显示为修改字段,但如果您重新打开视图,原始值将 return.
这是一个处理插入、更新或删除的触发器。请注意,在发生更新时,会填充插入和删除结果集。这不是处理事情的最有效方式,但您正在更新 Access 中的链接视图,所以...
CREATE TRIGGER vwInvoices_Modify ON vwInvoices
INSTEAD OF INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON;
-- delete non-updates
DELETE FROM PreliminaryInvoices WHERE Id IN (
SELECT Id FROM deleted EXCEPT SELECT Id FROM inserted
);
-- insert non-updates
INSERT INTO PreliminaryInvoices (Id, colA, colB)
SELECT Id, colA, colB FROM inserted WHERE Id NOT IN (SELECT Id FROM deleted)
-- updates
UPDATE PreliminaryInvoices SET
colA = ins.colA
colB = ins.colB
FROM inserted ins
WHERE ins.Id IN (SELECT Id FROM deleted)
AND PreliminaryInvoices.Id = ins.Id
END
根据我的阅读,如果被修改的数据仅表示一个 table 并且数据中包含一个唯一标识符字段,则应该可以编辑视图描述的数据。
根据微软
Any modifications must reference columns from only one base table
当底层记录集基于合并来自两个 table 的数据的视图或存储过程时,是否有人幸运地创建了 editable 的 MS-Access 表单?
我的表单只使用辅助 table 加入代码 table 以获得基于文本的描述 - 但这样做会使表单成为 uneditable.
我是否需要将其提取出来并为表单创建额外的查找代码?或者是否有人可以向我指出适合他们的示例?
这是我尝试用于编辑的表单的视图现在的样子 PreliminaryInvoices
table
SELECT t1.*, t2.JobTypeGroup AS Grouping
FROM dbo.PreliminaryInvoices AS t1
INNER JOIN dbo.tblJobTypes AS t2
ON t1.JobTypeID = t2.JobTypeID
编辑 - 更新以显示当前工作解决方案 - 没有第二个 table
我能够让它工作的唯一方法是拆分第二个 table 并添加一个查找以显示来自 JobTypeID
的文本当前 Editable 查看:
SELECT t1.*
FROM dbo.PreliminaryInvoices AS t1
查找程序:
CREATE PROCEDURE [dbo].[spJobTypeGrouping]
-- Add the parameters for the stored procedure here
@TypeID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT dbo.tblJobTypes.[Grouping]
FROM dbo.tblJobTypes
WHERE dbo.tblJobTypes.JobTypeiD = @TypeID
END
如果您想更新无法从 Microsoft Access 中完全更新的视图,我建议您使用 SQL 服务器中的触发器来执行更新。
您可以定义一个 INSTEAD OF UPDATE
触发器来覆盖默认更新行为。
您可以在 MSDN 上阅读有关 INSTEAD OF
触发器的信息。这些允许您准确指定更新字段时发生的情况,甚至允许您更新计算列(例如,更改计算年龄列时更改某人的生日)。
要使用 T-SQL 查询和可更新视图,您需要将表单绑定到 ADO 记录集。您可以使用类似于以下代码的代码:
Private Sub Form_Load()
Dim conn As ADODB.Connection
'Open a valid connection here. I recommend a reusable function or class for opening connections
Dim rs As ADODB.Recordset
Set rs = conn.Open("SELECT * FROM dbo.MyView")
Set Me.Recorset = rs
End Sub
您应该在视图上创建 instead of
触发器,以便更新基础 table。您不必更新触发器中的所有字段。如果您创建了适当的触发器,Access 会将其视为 table。
至于您的触发器未涵盖的字段。如果用户尝试更新 table,UI 将显示为修改字段,但如果您重新打开视图,原始值将 return.
这是一个处理插入、更新或删除的触发器。请注意,在发生更新时,会填充插入和删除结果集。这不是处理事情的最有效方式,但您正在更新 Access 中的链接视图,所以...
CREATE TRIGGER vwInvoices_Modify ON vwInvoices
INSTEAD OF INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON;
-- delete non-updates
DELETE FROM PreliminaryInvoices WHERE Id IN (
SELECT Id FROM deleted EXCEPT SELECT Id FROM inserted
);
-- insert non-updates
INSERT INTO PreliminaryInvoices (Id, colA, colB)
SELECT Id, colA, colB FROM inserted WHERE Id NOT IN (SELECT Id FROM deleted)
-- updates
UPDATE PreliminaryInvoices SET
colA = ins.colA
colB = ins.colB
FROM inserted ins
WHERE ins.Id IN (SELECT Id FROM deleted)
AND PreliminaryInvoices.Id = ins.Id
END