Sqlite view across multiple databases - view

Is it possible to create a VIEW (not temporary view) in a Sqlite database that has other databases attached to it?
The view should be able to access data from all databases via joined tables.

No, the view must be temporary, otherwise an error will occur:
sqlite> create view view1 as select * from db2.foo union select * from main.foo;
Error: view view1 cannot reference objects in database db2
sqlite> create temp view view1 as select * from db2.foo union select * from main.foo;
sqlite> select * from view1;
...
This makes sense since a temporary view is part of the automatically created temp database which only exists for the current process.
EDIT:
You can list the temporary tables and views (all stored in the automatically created temp database) this way:
sqlite> .headers on
sqlite> select * from sqlite_temp_master;
type|name|tbl_name|rootpage|sql
view|view1|view1|0|CREATE VIEW view1 as select * from db2.foo union select * from main.foo
To list views only:
select * from sqlite_temp_master where type='view';

Related

Oracle puzzle: Selecting from a non-existing table

I have a table named "libisatz" in my database, and there is no table, nor view with name "libiSatz" (with capital S instead of s) and I don't find any kind of object in my schema having name "libiSatz". But, surprisingly selecting from "libiSatz" results in the same result as if I had written "libisatz". If I change any other letter in this name from lower case to upper case (e.g. I write "Libisatz", then I get an error. How can this be?.
ADDENDUM
I've checked the ideas of #Jon Heller with the following result:
Both select * from DBA_OBJECTS where OBJECT_NAME like 'libi_atz'; and select * from DBA_OBJECTS where lower(OBJECT_NAME) = 'libisatz'; returns one single row (it is the "libisatz" table)
select * from DBA_OBJECTS where OBJECT_NAME = 'libisatz'; returns one row and select * from DBA_OBJECTS where OBJECT_NAME = 'libiSatz'; returns no row.
Both select * from DBA_SQL_TRANSLATIONS; and select * from DBMS_ADVANCED_REWRITE; results in ORA-00942: table or view does not exist
select * from DBA_REWRITE_EQUIVALENCES; results in no rows selected
select DUMP(OBJECT_NAME) from DBA_OBJECTS where lower(OBJECT_NAME) = 'libisatz'; returns Typ=1 Len=8: 108,105,98,105,115,97,116,122
So it seems that the puzzle is not yet solved.
ADDENDUM 2.
When I try to create a view named "libiSatz" then I get
ORA-00955: name is already used by an existing object
in spite of the results above.
After I renamed "libiSatz" to "oraclepuzzle",
select count(*) from "libisatz"; and "select count(*) from "oraclepuzzle"; works, but select count(*) from "libiSatz"; doesn't.
select * from dba_objects where object_name in ( 'oraclepuzzle', 'libisatz', 'libiSatz'); returns one row with object_name "oraclepuzzle".
Do you have SQL translations, rewrite equivalances, or UTF8 characters?
The SQL translation framework was built to allow applications designed for other database types to seamlessly query Oracle. But instead of translating syntaxes, the feature could also be used to silently change your queries. For example, here is an example of querying a table that does not exist in order to workaround table size limitations. Check the view DBA_SQL_TRANSLATIONS.
Rewrite equivalences can be created by the package DBMS_ADVANCED_REWRITE, and can be used to silently change the results of wrong queries or for some rare performance problems. (In my simple tests I wasn't able to get this query to work for invalid queries, but I bet there is a way to make it work.) Check the view DBA_REWRITE_EQUIVALENCES.
UTF8 characters may be silently swapped out for similar ASCII characters. This probably depends on your database and client character set settings. The below example is pretty obviously not an ASCII "S", but you may have a more subtle problem. Check the source of your values, retype them manually, and use the DUMP function to evaluate the binary of the characters.
SQL> create table "libisatz"(a number);
Table created.
SQL> -- An uppercase "S" does not work
SQL> select * from "libiSatz";
select * from "libiSatz"
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> -- But a "LATIN SMALL LETTER S WITH CARON" works.
SQL> select * from "libiĆĄatz";
no rows selected
Lastly, are you 100% sure that the object doesn't exist on your database? The above examples are possible, but extremely rare. Triple-check DBA_OBJECTS.OBJECT_NAME for the mystery object.
My deafult Oracle object names are case insensitive.
So, when you issue teh command:
CREATE TABLE the_table ..
CREATE TABLE The_Table ..
CREATE TABLE THE_TABLE ..
The underlying object name in all cases is THE_TABLE, but you can access it using any mix of upper/lower case:
SELECT * FROM THE_TABLE
SELECT * FROM tHe_TaBlE
SELECT * FROM the_table
Will all work.
When a table is created with the name wrapped in double-quotes, the name becomes case-sensitive.
So, if you issue:
CREATE TABLE "libiSatz" ..
Then the table name in all SQL statements must match the exact name in the double quotes, i.e.
SELECT * FROM "libiSatz" is OK (Correction following comments)
SELECT * FROM libisatz is NOT OK
SELECT * FROM LibiSatz is NOT OK
When you search for this in USER_OBJECTS or USER_TABLES you will have to match the creation name:
SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME = 'libiSatz';

Where is this Oracle object?

I have some SQL scripts; one of them references an object called "names". I can:
select * from names
and it returns results. However, I cannot see a table called "names". Neither can I see a view called "names". I can't find a custom type called "names".
If I look for one of the columns that is returned by the query select * from names using:
select * from sys.all_tab_columns where column_name like '%MyColumn%'
it finds a table called LSNAMES, but that has no rows.
Any ideas how I can find this "table"?
I'd start the research with understanding what type of object this is:
SELECT owner, object_name, object_type
FROM all_objects
WHERE object_name = 'NAMES'
Once you have a type, you could query some more information from all_<type>s
Look for:
A materialized view called NAMES
SELECT * FROM ALL_MVIEWS WHERE MVIEW_NAME = 'NAMES';
A synonym called NAMES
SELECT * FROM ALL_SYNONYMS WHERE SYNONYM_NAME = 'NAMES';

How to select * from table () referencing a function from dblink

I'm just starting with PL/SQL. I have a function (table valued), and I can select it running:
SELECT *
FROM TABLE(fn_getsomething());
Ok, but I have to select a similar function (table valued as well) from a remote database #dbfs. How can I write this sentence?
I tried:
SELECT *
FROM TABLE (fn_get_rps_to_rm#dbfs())
//or
SELECT *
FROM TABLE (fn_get_rps_to_rm()#dbfs());
And it returns : 00904. 00000 - "%s: invalid identifier"
I had looked for similar questions, talking about table valued functions and dblink and I didn't find it.
I would recommend creating a view on the remote node say:
create or replace view fn_getsomething_view as
SELECT *
FROM TABLE(fn_getsomething());
then query from that view with the link, for example:
select * from fn_getsomething_view#dbfs;
hope this helps.

Create materialised view without data

I need to create materialized view test without data then I will create a script to insert data into this materialized view for the first time. After this I will run materialized view refresh to refresh the view every night.
As I am not expert in materialized views can anyone help me here.
At present I have script to create materialized view which is running for 2 hours for 20 million rows.
create materialize view
If I understand the question correctly, you want to break up the MV creation into separate steps:
Create an empty table / materialized view.
Populate it.
Schedule a nightly refresh process.
For this you can use the on prebuilt table clause to change a normal table into a materialized view.
Demo source table:
create table demo_source (id, name) as
select 1, 'Red' from dual union all
select 2, 'Yellow' from dual union all
select 3, 'Orange' from dual union all
select 4, 'Blue' from dual;
New table which is going to be our MV (you could also populate it with the create table as select, or you could create it using explicit column names, datatypes, constraints, partitioning etc like any normal table):
create table demo_mv as
select * from demo_source s
where 1 = 2;
Populate it using a separate insert step:
insert into demo_mv
select * from demo_source;
Now we convert it from a regular table into an MV:
create materialized view demo_mv on prebuilt table
as
select * from demo_source;
Now DEMO_MV is a materialized view.
If I were you, I'd create the materialized view "as is" (i.e. no restrictions you mentioned).
Anyway: the simplest option is to include the false condition in the WHERE clause which creates the object without data, such as
SQL> create materialized view mv_dept as
2 select * from dept
3 where 1 = 2; --> this
Materialized view created.
SQL> select * from mv_dept;
no rows selected
SQL> desc mv_dept;
Name Null? Type
----------------------------- -------- --------------------
DEPTNO NOT NULL NUMBER(2)
DNAME VARCHAR2(14)
LOC VARCHAR2(13)
SQL>
I know this question was asked specifically about Oracle, but I got here looking for the same question about Postgres.
Luckily, Postgres has a 'WITH NO DATA' clause at the end of the materialized view statement that just creates the view but does not populate data into it. It can still be refreshed on-demand the same way after that.
https://www.postgresql.org/docs/current/sql-creatematerializedview.html
I have the same problem. At deploy time I don't want that the refresh takes to0 much time. So here I think is a better solution.
drop materialized view test_mv;
create materialized view test_mv
as select * from all_objects
where 1 = ( select count(*) from user_tables where table_name = 'TEST_MV' ) ;
select * From test_mv
=> null
exec DBMS_MVIEW.REFRESH('TEST_MV', method => 'C', atomic_refresh => FALSE, out_of_place => false , PARALLELISM => 4);
select * From test_mv
=> result is now of all objects

Oracle query that will list of the database objects referenced by a view

Is there an Oracle view that will list all of the database objects referenced by the DDL of a given view, procedure, or function?
So if a view is defined as:
CREATE OR REPLACE VIEW_B AS
SELECT * FROM TABLE_A INNER JOIN VIEW_A
running a query on this system view:
SELECT REF_OBJECT_NAME, REF_OBJECT_TYPE FROM V$XXX WHERE OBJECT_NAME='VIEW_B'
would list something like:
REF_OBJECT_NAME REF_OBJECT_TYPE
TABLE_A TABLE
VIEW_A VIEW
Try:
select * from dba_dependencies
where owner = 'view owner'
and name = 'view name';

Resources