SQLite User Forum

A VIEW and the ATTACH DATABASE
Login

A VIEW and the ATTACH DATABASE

(1.2) By averageasker on 2022-04-29 05:15:27 edited from 1.1 [link] [source]

I'm researching possibilities around the ATTACH DATABASE. For that I created db1.db and db2.db where both have a Table1 with the same schema. Db2.db also defines a view:

    CREATE VIEW Table1View AS
    SELECT *
      FROM Table1;

Then I leveraged sqlite3.exe to first open db1.db and then attached db2.db, which makes the db1.db a "least recently attached", and then finally executed:

SELECT * FROM Table1View

To see which table - Table1 from db1.db or Table1 from db2.db will be used to grab the data from the Table1 composing the view.

Reading this from the above doc:

If two or more tables in different databases have the same name and the schema-name prefix is not used on a table reference, then the table chosen is the one in the database that was least recently attached.

I was hoping there is a way to instruct SQLite to apply that rule not only against SQL commands issued on this specific connection with 2 active DBs but also against a view definitions.

Once the above SELECT from the view was executed, I saw the data was returned from the Table1 defined in db2.db, the same one defining the view, but not from Table1 defined in db1.db which was "least recently attached".

If, however, I execute on this same connection:

SELECT * FROM Table1

I do see the data from db1.Table1 is retrieved this time.

This tells me the table resolution described in the "ATTACH DATABASE" doesn't apply to a compiled View but instead only applies to a SELECT statements executed on this connection while explicitly referencing the table.

Is there a way to instruct the engine to apply the same resolution to a view's definition so db1.Table1 would sort of "override" db2.Table1 while Table1 is being accessed by the View?

(2) By Gunter Hick (gunter_hick) on 2022-04-29 05:36:44 in reply to 1.2 [link] [source]

The view lives in db1, so why do you expect it to select from a table from db2? I expect that if you create the same view in db2, that view will be chosen and return values from db2.Table1.

Note that some time ago creating cross-database views was prohibited (except for TEMP) because it creates subtle interdependencies that would cause views to malfunction if the databse containing the referenced table was not attached.

This has been a mild irritation to us, as we keep virtual tables referring to external storage in a separate database from virtual tables that work as table valued functions be decomposing tags (structures identified by tag number) and taglists (concatenation of tags). Views that previously could be stored in MAIN and reference TAGS now have to be loaded into TEMP at runtime.

(3) By averageasker on 2022-04-29 07:21:23 in reply to 2 [link] [source]

The view lives in db1, so why do you expect it to select from a table from db2? I expect that if you create the same view in db2, that view will be chosen and return values from db2.Table1.

Not like I literally expect but rather I was wondering if that will take place after reading ATTACH DATABASE which states

If two or more tables in different databases have the same name and the schema-name prefix is not used on a table reference, then the table chosen is the one in the database that was least recently attached.

Especially after I proved that works if I issue explicit query

SELECT * FROM Table1View

then, in my case, I did see the data from db1 was retrieved. But, when, essentially, the same query was executed via the View, the data in db1.Table1 didn't override db2.Table1 and a data from Table1 belonging to the db2 was returned.

Note that some time ago creating cross-database views was prohibited (except for TEMP) ...

Does that mean NOW it is possible to create those views outside of TEMP?

If that is still possible only in TEMP, as I understand the view created in TEMP is only alive in that specific connection. I wonder if there is a way to somehow "persisted" those cross DB views across multiple application's restarts. Just in case want to re-iterate: I'm looking for a possibility to have a persisted (created not in TEMP) View composing tables from different databases.

(4.1) By Gunter Hick (gunter_hick) on 2022-04-29 08:26:43 edited from 4.0 in reply to 3 [source]

NOW you can create only views that refer to the SAME database. Except for TEMP views. As you can see, the meaning of the view t1v changes. Is this what you were looking for?

SQLite version 3.24.0 2018-06-04 19:24:41
$ attach 'db1.db' as DB1;
$ create table db1.t1 (db1 integer primary key, value text);
$ insert into t1(value) values ('eins');
rows inserted
-------------
1
$ attach 'db2.db' as DB2;
$ create table db2.t1 (db2 integer primary key, value integer);
$ insert into db2.t1(value) values (2);
rows inserted
-------------
1
$ select * from t1;
db1         value
----------  -----
1           eins
$ create temp view t1v as select * from t1;
$ select * from t1v;
db1         value
----------  -----
1           eins
$ detach DB1;
$ select * from t1v;
db1         value
----------  ----------
1           2

EDIT: Just noticed that the SOURCE of the data changes, but NOT the column names. But one should be specifying column names anyway if one is particular about them.