update a specific column in a view - sql

In my knowledge view is a virtual table, which contains rows and columns, just like a real table and use for view the data.
Is it possible to update a specific column in a view.
For Example:
update dbo.MyView
set [column1] = "some value"
where [column2] = "some value"

In general, you don't want to update views, unless the database has been designed for that purpose. In general, you want to update the tables are comprise the view.
In SQL Server, you can update a view under two circumstances.
The first is when the view is an updatable view. Such views have to have certain very specific conditions, which are described in the documentation.
The second is when the view has an instead of update trigger on it. This is a trigger that (typically) updates the underlying tables.

Related

Update Query Timeout on SQL Server View with MS Access

I am having some trouble with updates to an SQL Server View through MS Access. The set of tables used for this is built off of a base table. This base table is of this format.
Id int (not-nullable; auto-assigned)
A1 varchar(50) (nullable)
A2 varchar(50) (nullable)
B1 varchar(50) (nullable)
B2 varchar(50) (nullable)
C1 varchar(50) (nullable)
C2 varchar(50) (nullable)
One row on this table is updated by multiple groups of users in our company. For instance, user group "A" updates columns "A1" and "A2", user group "B" updates columns "B1" and "B2", and so forth. However, we also want to prevent user group "A" from updating the columns of user group "B". To accomplish this, I set up a view containing the columns appropriate for each user group. For instance, the view for user group "A" would only contain the columns "Id", "A1", and "A2". Then I set the "Bind To Schema" option on the views in SSMS to "Yes", and I set up a unique, clustered index on the "Id" column on each of the views. In MS Access, I connect to these views as linked tables using an ODBC connection. When I open the tables in MS Access in design view and check the indexes, it does properly identify the "Id" column as the primary key.
Here is where the trouble comes in: When I try to update a record through MS Access in one of the views, sometimes the update runs instantly, but sometimes the update times out. Here is the error that I get.
"SM_Notes_Bridge" is the actual name of one of my views. Almost all previous answers that I can find online say to increase the amount of time before the update times out in MS Access, which seems like it is not a solution for my problem as the update either runs instantly or times out. There is no middle ground.
Another note is that I am currently the only one using this base table and these views. Also, important systems are developed around that base table structure, so changing its structure will take a lot of convincing.
By creating an unique index on a schema bound view, you're creating an indexed view, also called a materialized view.
A relevant property of indexed views:
When executing DML on a table referenced by a large number of indexed views, or fewer but very complex indexed views, those referenced indexed views will have to be updated as well. As a result, DML query performance can degrade significantly, or in some cases, a query plan cannot even be produced (MSDN).
Thus, creating multiple indexed views on a table that is updated often is a big no-no! Review this MSDN page for further explanation when and when not to use an indexed view. Every insert and update will have to propagate to all the indexed views, and will cause locks on those views as well.
Drop the indexes on ALL views on that table. As far as you've told me, there's no reason at all to use indexed views and they will hurt performance in a major way when executing updates. Even if that didn't fix this issue, it will improve performance.

Can a view be updated/inserted/deleted? If Yes under what conditions?

I googled above question and got the following answers
YES--> If it is in the case of simple view (which consists only one base table).
NO---->If it is in the case of complex view( which consists multiple base tables, and joins).
However, there is an indirect way of performing DML operations on Complex views, by using "Instead Of trigger". In the body of Instead of trigger we will use co-relational identifiers, and DML statements to perform DML operations indirectly on the complex view. Then that changes will reflect in base tables of that particular complex view.
here my question is does changes applied to view will have any effect on original tables?
If a View on a single base table is manipulated will the changes be reflected on the base table?
can any one give me example for the above cases?
In Oracle you can update a view under these conditions:
from: Oracle database SQL Reference
Notes on Updatable Views
An updatable view is one you can use to insert, update, or delete
base table rows. You can create a view to be inherently updatable, or
you can create an INSTEAD OF trigger on any view to make it
updatable.
To learn whether and in what ways the columns of an inherently
updatable view can be modified, query the USER_UPDATABLE_COLUMNS data
dictionary view. The information displayed by this view is meaningful
only for inherently updatable views. For a view to be inherently
updatable, the following conditions must be met:
Each column in the view must map to a column of a single table. For example, if a view column maps to the output of a TABLE clause (an
unnested collection), then the view is not inherently updatable.
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database
Administrator's Guide
In addition, if an inherently updatable view contains pseudocolumns or expressions, then you cannot update base table rows with an UPDATE
statement that refers to any of these pseudocolumns or expressions.
If you want a join view to be updatable, then all of the following conditions must be true:
The DML statement must affect only one table underlying the join.
For an INSERT statement, the view must not be created WITH CHECK
OPTION, and all columns into which values are inserted must come from
a key-preserved table. A key-preserved table is one for which every
primary key or unique key value in the base table is also unique in
the join view.
For an UPDATE statement, all columns updated must be extracted from
a key-preserved table. If the view was created WITH CHECK OPTION, then
join columns and columns taken from tables that are referenced more
than once in the view must be shielded from UPDATE.
For a DELETE statement, if the join results in more than one key-preserved table, then Oracle Database deletes from the first
table named in the FROM clause, whether or not the view was created
WITH CHECK OPTION.
In SQL Server, you can insert, update, and delete rows in a view, subject to the following limitations, Source
If the view contains joins between multiple tables, you can only insert and update one table in the view, and you can't delete rows.
You can't directly modify data in views based on union queries. You can't modify data in views that use GROUP BY or DISTINCT statements.
All columns being modified are subject to the same restrictions as if the statements were being executed directly against the base
table.
Text and image columns can't be modified through views.
There is no checking of view criteria. For example, if the view selects all customers who live in Paris, and data is modified to
either add or edit a row that does not have City = 'Paris', the data
will be modified in the base table but not shown in the view, unless
WITH CHECK OPTION is used when defining the view.

Creating Indexed View which references a Non Indexed View and objects from multiple DB's

I have the following objects used in the following format in a create view statement.
dbo.objects1 A
INNER JOIN db2.dbo.object2
INNER JOIN db2.dbo.object3
INNER JOIN db2.dbo.object4
INNER JOIN db2.dbo.object5
The objects1 is a table from Database1 which has Indexes. The objects2 through objects5 are in another database and all these 4 objects are view with No indexes.
Now I am trying to create an indexed view with all the above five objects but SQL server is not allowing me.
First error is:
Names must be in two-part format and an object cannot reference itself.
Second error is:
Cannot schema bind view 'dbo.vw_Order' because name 'db2.dbo.object2' is invalid for schema binding.
Now I googled these errors and I came to following assumptions:
Views cannot contain objects from multiple databases in a join query.
In order to create indexes on a view, all the objects in the view should have either indexes or should be schema binded (like Functions).
When I run the view like a query, Execution Plan is recommending me to create an index on columns from objects in db2. Please let me know if my assumptions are correct. If not, please let me know a way as to how I can create a view in this situation.
As you have already done the research that all the objects(tables/View) in a definition of an indexed view must have TWO PART name i.e [Schema].[Object] it means all the objects will be in one database and you cannot create indexed view across multiple databases. Indexed views come with a lot of limitations, consider creating a stored procedure if possible
Other error that you are getting is you are missing WITH SCHEMABINDING option in your view's definition. It is a must requirement for creating an indexed view that you must use the WITH SCHEMABINDING option when creating indexed view i.e none of the underlying tables/objects schema can be changed until you drop this view.
Again I would suggest to look into stored procedures as it seems impossible in your case to create an Indexed View because of all the limitation that come with it.
Add the owner to the view name and tables.
Like:
Create VIEW dbo.MyView
WITH SCHEMABINDING
AS
SELECT * From dbo.Users
You cannot create indexed view using two objects of different databases.

Impact: Delete a View, Create table with same name

So there was this VIEW in oracle named XYZ and somebody says, we are going to replace it with a TABLE of the same name.
What kind of an impact can this create to existing SQL's written on that view?
Is the syntax for querying a VIEW same as that for a TABLE?
By "... replace it with a table ..." I assume you mean that a table is created with the same data the view was referencing. In other words, the new table redundantly contains data from other tables (those that the view was referencing).
SELECT-Statements will not need to be changed - the syntax is the same.
BUT: The view will immediately reflect changes in underlying tables. The table obviously not - it will have to be kept in sync by triggers or application logic. So depending on the view, this might be a rather big change. Even more so if the view was updateable.
Example:
Suppose the view was defined as ... select a.key, b.name from a,b where b.key = a.b_ref
Then selecting from the view will always reflect changes to tables a and b.
If you replace it by a table, you would have to update that new table every time you update table a or b.
As long as the columns are identical in Name DataType and DataLength, then there will be no impact.
SQL SELECT statments essential treat VIEWS and TABLE as the same things.

If I update a view, will my original tables get updated

Hypothetically I have two tables Employee and Locations. Additionaly I have a view viewEmpLocation which is made by joining Employee and Locations.
If I update the view, will the data in the original table get updated?
Yes.
The data "in" a view has no existence independent from the tables that make up the view. The view is, in essence, a stored SELECT statement that masquerades as a table. The data is stored in the original tables and only "assembled" into the view when you want to look at it. If the view is updateable (not all views are) the updates are applied to the table data.
see Using Views in Microsoft SQL Server
When modifying data through a view
(that is, using INSERT or UPDATE
statements) certain limitations exist
depending upon the type of view. Views
that access multiple tables can only
modify one of the tables in the view.
Views that use functions, specify
DISTINCT, or utilize the GROUP BY
clause may not be updated.
Additionally, inserting data is
prohibited for the following types of
views:
* views having columns with derived (i.e., computed) data in the SELECT-list
* views that do not contain all columns defined as NOT NULL from the tables from which they were defined
It is also possible to insert or
update data through a view such that
the data is no longer accessible via
that view, unless the WITH CHECK
OPTION has been specified.
You could use a trigger on the view to do an insert/update/delete to the actual tables.
http://www.devarticles.com/c/a/SQL-Server/Using-Triggers-In-MS-SQL-Server/1/