I am porting an Access front end/Access back end application to Access front end/SQL Server back end and am having trouble with a particular form. I think its because I do not properly understand the underlying concepts in what I am trying to do. In particular Updating Data through a view.
Its a resource booking application, where I have “clients”, known primarily through their clientID trying to book a “resource” (known by its resourceID) in a “diary”. Each record in the “diary” is a booking, containing the date and time of the booking together with the clientID and resourceID.
In the existing Access application I have a query as the record source for the form which joins the diary and client via their mutual clientID. Something along these lines (although in the real thing many more fields are involved)
SELECT d.bookdate,d.booktime, d.clientID, c.clientID AS CID, c.name
FROM diary d INNER JOIN client c ON d.clientID = c.clientID
ORDER BY bookdate,booktime
I find that I can create a new diary record for a clientID by opening the form with
acFormAdd and OpenArgs set to clientID, and writing that in form load to a form field liked to the data field CID (c.clientID), thus
DoCmd.OpenForm "frmDiary", acNormal, , "ClientID = " & Me.ClientID, acFormAdd, , Me.ClientID
and then in frmDiary in the Form_Current sub
If Nz(Me.OpenArgs, "") <> "" Then Me.CID = Me.OpenArgs
the writing of the Me.CID field (which is the side of the query where the data already exists) causes a new record to be created in the diary table and at the same time populates the form with the correct data from the other fields from the Client Record.
In the SQL Server version of the application I dynamically create tabledefs to point to the tables in the correct instance of my SQL Server database during an initiation sequence. I also create tabledefs for appropriate views. I do it dynamically to enable me to switch between various versions of my database very easily.
Because my diary table is 80,000 records long and the client table is 40000 records long, I don’t particularly what the join of the two to take place in the Access client. I have therefore created a View on SQL Server that matches the select clause above (minus the order by) and created a tabledef for it during initialisation.
However the whole form does not work because it tells me the view is not updateable. This seems to be confirmed by opening the tabledef in as a datasheet in Access – there is no new record button in the navigation set.
I am struggling because
- I don’t understand how the db_datawriter role translates into privileges to write to the database. (my application connects as a server login which matches a database user who has the db_datawriter role assigned). So I have no idea if this extends to the view and whether my issue is a permissions issue. I am exploring the database with SQL Server Management Studio and looking at permission properties.
- I have read that only fields in a view that belong to one of the base tables from which the view is constructed can be updated. This makes my “trick” of writing the Me.CID field of my form to stimulate creation of the new diary record appear not to be the right approach.
So I am not sure what my next step should be. Any ideas?
One of the key elements of my question was “How do you make a view Updateable?”. The simple answer it to give it a UNIQUE CLUSTERED INDEX.
I found that although you can create on a view, if you ever alter the view (like to add an additional field) you need to recreate the index because it gets deleted.