Select Data from view vs Table of same name - sql

I have a database where a view and a table have same name, when I try to execute query
select * from XXXXXXXXX
from where is this data coming from, view or table? Is there any explicit declaration syntax to tell, to where from select the data?
PS: the DB owner is different so I can't change the structure of view/table or names either.

Objects names are unique per owner, so the table and the view can't be defined for the same owner.
Qualify the table/view name with the right owner.
select * from table_owner.XXXXXXXXX
select * from view_owner.XXXXXXXXX

Related

Azure hosted SQL: show all fields in a table as a saved View

Probably a simple answer, but assume I have a table with 3 columns:
ab, cd, ef
I create a new view
SELECT *
FROM tbl
It works. I save the view, SSMS automatically changes the saved version of the view to say:
SELECT dbo.tbl.ab, dbo.tbl.cd, dbo.tbl.ef
How do I keep the saved version of the view to include all columns in tbl rather than explicitly identifying each column?
You can create the view like this:
CREATE VIEW vwTbl
AS
SELECT *
FROM tbl
Then you can query the view to retrieve all columns like:
SELECT * FROM vwTbl

Using a select statement to define a table name

I am trying to create snapshot tables as part of script I run regularly.
At the moment I have to manually enter table names, but I would like to call on a field in the base data table to create the snapshot table name.
For example:
Base Data Table = base_data and contains a field for the month it was created in.
Snapshot table = base_data_month
I have already tried to run this to create an automatically named table...
create table base_data_snapshot_||(select month from base_data) as
select * from base_data
But this gets a syntax error. For reference there is only one month included in the base data.
Has anyone had any success with this before?
Although we cant combine a running create statement with a select but can use select. So, I guess below should work
create table
base_data_snapshot_||t.month
as
( select * from base_data) t

How to pass list of IDs from one Oracle schema to another?

I use the Oracle SQL developer to query the Oracle database
So, my simplified script is as follows:
alter session set current_schema=schema1;
select id from table1
alter session set current_schema=schema2;
select * from table2 where remote_id in (<the list from the 1st query in schema1>)
Currently I copy the list from one schema to another manually. How to automate passing the list?
Fully qualified database object references in Oracle are SCHEMANAME.OBJECTNAME so regardless of which schema is your current schema, you can reference objects in other schemas like so:
Select *
from schema2.table2
where remote_id in (select id from schema1.table1);

Refresh view in HSQL

I would like to update a view in HSQL without writing the same statement again and again.
I have a table CONTACTS with ID, First_NAME and LAST_NAME. I also have a VIEW for this table, which I created with
CREATE VIEW IDGREATERTHREE AS SELECT * FROM CONTACTS WHERE ID > 3;
How can I update my VIEW after I added a new column to my table. I want to update my table without anything like this:
ALTER VIEW IDGREATERTHREE AS SELECT * FROM CONTACTS WHERE ID > 3;
I would like to find a way to refresh my invalid view in a similar way like in Oracle:
ALTER VIEW IDGREATERTHREE COMPILE;
I am also looking for a way to select just the invalid views. WithSELECT * FROM INFORMATION_SCHEMA.VIEWS I am not able to see any difference between an invalid and a non-invalid view.
A solution for this would be to write an ON DDL trigger.
In this ON DDL trigger , you check if your modifying your table.
If this is the case, then you use Dynamic SQL to recreate your view. This is doable with plsql (you tagged with oracle). There is ample documentation on creating triggers and dynamic SQL on the Internet.
HSQLDB cannot have invalid views. When you create a view, the SELECT * FROM CONTACTS is expanded to the actual column names. When you add a column to the table the view is recompiled with the original column names and the new column is not included.

How to auto-redefine view when underlying table changes (new column)?

We've got a view that's defined like this
CREATE VIEW aView as
SELECT * from aTable Where <bunch of conditions>;
The "value" of the view is in the where-condition, so it is okay to use a Select * in this case.
When a new column is added to the underlying table, we have to redefine the view with a
CREATE OR REPLACE FORCE VIEW aView as
SELECT * from aTable Where <bunch of conditions>;
as the Select * seems to get "translated" into all the columns present at the time the view is (re-)defined.
My question: How can we avoid this extra step?
(If the answer is dependent on the RDBMS, we're using Oracle.)
I know you specified Oracle, but the behavior is the same in SQL Server.
One way to update the view with the new column is to use:
exec sp_refreshview MyViewName
go
Of course, I also agree with the other comments about not using a SELECT * in a view definition.
This extra step is mandatory in Oracle: you will have to recompile your view manually.
As you have noticed, the "*" is lost once you create a view:
SQL> create table t (id number);
Table created
SQL> create view v as select * from t;
View created
SQL> select text from user_views where view_name = 'V';
TEXT
-------------------------------------------------------
select "ID" from t
You should not be using * in your views. Specify the columns explicitly.
That way you are only retrieving the data you need, and thus avoid potential issues down the road where someone adds a column to a table that you do not want that view to return (e.g., a large binary column that would adversely impact performance).
Yes, you need to recompile the view to add another column, but this is the correct process. That way you avoid other compilation issues, such as if the view reference two tables, and someone adds a duplicate column name in one of the tables. The compiler would then have issues determining which of the columns was being referred to if you did not prefix a reference to the column with a table alias, or it might complain if there are duplicate column names in the results.
The problem with automatically updating views to add columns comes when you extend your model, for example to
SELECT a.*, std_name_format(a.first_name, a.middle_names, a.last_name) long_name
or even
SELECT a.*, b.* from table_a a join table_b b....
If you have a view of just SELECT * FROM table, then you probably should be using a synonym or addressing the table directly.
If the view is hiding rows (SELECT * FROM table WHERE...), then you can look at the feature variously known as Fine Grained Access Control (FGAC), Row Level Security (RLS) or Virtual Private Database (VPD).
You might be able to do something with a DDL trigger but that would get complicated.