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

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.

Related

Error while dropping column from a table with secondary index (Scylladb)

While dropping a column from a table that contains secondary index I get the following error. I am using ScyllaDB version 3.0.4.
[Invalid query] message="Cannot drop column name on base table warehouse.myuser with materialized views"
Below are the example commands
create table myuser (id int primary key, name text, email text);
create index on myuser(email);
alter table myuser drop name;
I can successfully run the above statements in Apache Cassandra.
Default secondary indexes in Scylla are global and implemented on top of materialized views (as opposed to Apache Cassandra's local indexing implementation), which gives them new possibilities, but also adds certain restrictions. Dropping a column from a table with materialized views is a complex operation, especially if the target column is selected by one of the views or its liveness can affect view row liveness. In order to avoid these problems, dropping a column is unconditionally not possible when there are materialized views attached to a table. The error you see is a combination of that and the fact that Scylla's index uses a materialized view underneath to store corresponding base keys for each row.
The obvious workaround is to drop the index first, then drop the column and recreate the index, but that of course takes time and resources.
However, in some cases columns can be allowed to be dropped from the base table even if it has materialized views, especially if the column is not selected in the view and its liveness does not have any impact on view rows. For reference, I created an issue that requests implementing it in our bug tracker: https://github.com/scylladb/scylla/issues/4448

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.

SQL: View and table

If I create a view, is the view reflect physical table real time or it is just a materialized view and synchronize with physical table every n seconds/minutes. If I want to update something, may I update the materialized view, then would db synchronize the view and table?
The view reflects the table structure. Any changes made to the tables data will be reflected in the view.
Yes, you may update data using views, changes will apply to the base table immediately. In fact views do not contain any data at all.

Create Index on partial CHAR Column

I have a CHAR(250) column being used as a foreign key to a varchar(24) column.
In MySQL I recall that I could create an index specifying column(24) in order to create an index on the leftmost 24 characters. This doesn't appear to be possible on MS SQL Server.
My question is this:
Is it possible to use an indexed view on SQL Server 2008 to index a substring of that column, and if so, would it have any side-effects on the table's performance?
You can create a persisted computed column, then index it, see Creating Indexes on Computed Columns
alter table add newcolumn as cast(oldcolumn as varchar(24)) persisted;
create index table_newcolumn on table (newcolumn);
I hope you have a good relational reason for doing this. I'm guessing the first 24 characters of the vendor-provided table actually constitute a discrete attribute and should have been in a separate column in the first place.
So...
Create a view of the vendor's table. Index it if you like. I doubt you can point a FK constraint at the view, but you certainly can write a trigger to the same effect. A trigger checking against an indexed view will be very fast, at the cost of a slight increase in update times on the view's base table.
HTH.