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

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.

Related

How to create a read only view in postgresql , similar to oracle?

I want to create read only view in PostgreSQL. We can create in Oracle, but unable to do in PostgreSQL.
I tried to create a read only view but I get a syntax error at READ ONLY.
CREATE OR REPLACE VIEW VIEW NAME()
from table names
where filter condition1=filter
condition2
with READ ONLY;
But the READ ONLY doesn't work in PostgreSQL. How do I create a read only view in PostgreSQL?
I don't think that Postgres provides a way to explicitly define a view as read-onöy.
The documentation states:
Simple views are automatically updatable
However:
A more complex view that does not satisfy all these conditions is read-only by default.
The documentation lists the limitations of read-only views:
A view is automatically updatable if it satisfies all of the following conditions:
The view must have exactly one entry in its FROM list, which must be a table or another updatable view.
The view definition must not contain WITH, DISTINCT, GROUP BY, HAVING, LIMIT, or OFFSET clauses at the top level.
The view definition must not contain set operations (UNION, INTERSECT or EXCEPT) at the top level.
The view's select list must not contain any aggregates, window functions or set-returning functions.
Simple views are automatically updatable: the system will allow INSERT, UPDATE and DELETE statements to be used on the view in the same way as on a regular table. A view is automatically updatable if it satisfies all of the following conditions:
The view must have exactly one entry in its FROM list, which must be a table or another updatable view.
The view definition must not contain WITH, DISTINCT, GROUP BY, HAVING, LIMIT, or OFFSET clauses at the top level.
The view definition must not contain set operations (UNION, INTERSECT or EXCEPT) at the top level.
The view's select list must not contain any aggregates, window functions or set-returning functions
Unless your view satisfies all conditions, it is read-only. If you have a simple view that you want to make read-only, a (suboptimal) option would be to tweak its definition so it violates one of the above rules.
For example, you can add a dummy WITH clause:
CREATE VIEW myview AS
WITH dummy AS (SELECT 1)
-- real view definition here
You should handle this with permissions in PostgreSQL.
Just make sure that nobody has permissions to modify the view.
Note that you can also revoke privileges from the view owner.
Another approach is to create a fake join. Any joins immediately disqualify it from being an updatable view. For example:
CREATE VIEW public.west_country as select
city.id,
city_name,
country_id
from public.city
where city.country_id = 1
WITH CHECK OPTION;
This would create an updatable view. But if you use the code snipped below with the join statement it will be read only.
CREATE VIEW public.west_country_rw as select
city.id,
city_name,
country_id
from public.city
left join (select -1 as "id" ) as tmp on tmp.id = city.id
where city.country_id = 1;

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.

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.

Sql Server: altering a view makes clustered and full-text search indexes to be deleted

Scenario
I have got two tables: tblA and tblB, with the same structure. Every moment, one of them is online, and the other one is in stand by. Periodically data are updated in the stand by table, it goes online and the other one goes in stand by.
This procedure cannot be modified.
There is a trivial view that accesses the tables. Let's say vw:
create view vw as
select * from tblA
go
When the tables switch, the view is altered:
alter view vw as
select * from tblB
go
Issue
Now I have to create a full-text index on the view. No problem in creating the index.
But when I alter the view, the index is deleted.
I figure out that I have to recreate the full-text index every time I alter the table. But I wonder whether another solution exists.
This happens to all views, including standard indexed views. It is annoying.
From ALTER VIEW docs
ALTER VIEW can be applied to indexed views; however, ALTER VIEW unconditionally drops all indexes on the view.
No workaround exists: you have to recreate the view index or index the base table.

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/