Spring: best way to fetch field from Oracle v$database - spring

I have an Oracle database and need to periodically access some data from the v$database view in my SpringBoot app. v$database is a special view that has just one row and contains some internal DB constants and variables. Basically I would like to fetch CHECKPOINT_CHANGE# from that one row via a query such as:
SELECT CHECKPOINT_CHANGE# FROM v$database;
Normally, you would use the Spring Data Repository abstraction along with #Query for your usual tables/views and I'm sure that would work here, as well. But considering the fact that v$database is a bit "special" and only has one row, it seems a bit over the head.
How would you approach this?

There is nothing special about it as far as the user is concerned. It queries like any other table. Under the covers, it is an interface to the control file rather than a data segment, but that is only of interest on the back-end. Just don't try to ask for ROWID. And you will need the "SELECT ANY DICTIONARY" privilege to query it, as with all SYS-owned dictionary views.

Related

Role or User based access to TDE encryption in Oracle

Env: Oracle 11g DB with a Java based application
We are looking to encrypt data in our database, for a few sensitive columns of a table.
We would like these columns to be decrypted and visible to a set of users A.
And we DO NOT want these encrypted columns to be visible to another set of users B.
But, this user set B should be able to see the rest of the non-encrypted columns of the table.
From various articles and posts, I understand TDE does encryption and decryption transperantly and at column level, but have not been able to find clear information if the above user/role based encryption, at a column level granularity is possible or not.
Can we achieve the above using TDE?
I'm not a DBA, but from my understanding of TDE the encryption is not noticeable when viewed from any query. It only encrypts the data in the disk data file so it can't be read if dumped directly from the file.
A good DBA may have a better answer but just off the cuff, here is what I would suggest.
Have two fields for the sensitive data. One is clear (though TDE may be a good idea) and the other is obfuscated in some way. These fields may be normalized into a separate table. Don't allow access directly to the table but use a view instead. The view would be defined like:
create view TableName as
select ...,
case ROLE when 'A' then clear_field else obfuscated_field end as FieldName,
...
from SensitiveTable
join PossibleNormalizedTable on ... ;
You would also need triggers on the view. If only A can clearly see that field, probably only A can insert and update it.

Oracle, Preventing access to ALL_*/USER_* views

I'm assuming that it CAN be done, I just don't know how or haven't been able to find a way to do it.
In Oracle, can access to the ALL_* tables and USER_* tables be revoked, including select grants.
For example, the all_objects, all_procedures views. Can access to these be restricted?
The same goes for user_tables and user_procedures and any other user_* views. Can access to them be restricted?
No, you can't (reasonably) prevent users from being able to query the ALL_* or USER_* views. You could go through and individually revoke access to each and every one of these views from PUBLIC but that would be a rather painful effort to go through, it would cause all sorts of applications to break not to mention breaking scripts from Oracle. You would end up, at a minimum, re-granting access to those views to any account that connected to the database because every database API interrogates the data dictionary views. Whether you have an ODBC application, a JDBC application, a PL/SQL IDE like TOAD or SQL Developer, or just about anything else, those applications will need to query the data dictionary.
The data that they will see in either view, however, will be limited to the objects that they have access to (for the ALL_* views) or the objects that they own (for the USER_* views). What purpose would be served by restricting a user's ability to query the data dictionary to determine what objects the user owns or what objects the user has access to? It would seem extremely odd to want a user to own a table but then to not allow the user to know that he owned that table.
Now, if you are really determined, you can create objects in the user's schema (tables or views) named, say, ALL_TABLES or USER_TABLES. Assuming that the user just queries ALL_TABLES rather than specifying a fully qualified SYS.ALL_TABLES, they will be querying the local object not the data dictionary view. That is generally a very inadvisable thing to do-- lots of products work by querying the data dictionary so causing the data dictionary queries to return the wrong set of data can lead to all sorts of bugs that are terribly hard to track down. But it is an option if you really, really want to restrict what data is returned from the data dictionary.

Retrieving tables from "Other users" in nHibernate

First of all I won't to say that I'm an expert in database handling, and less so in oracle. However right now I need to get better at it :)
I'm using nHibernate as orm, to my oracle database. It works ok, and is rather simple to use. However now I have run in to a problem that I don't know how to solve.
In the Database theres a kind of tree with the tables, views, indexes and such. At the end there are also a entry called "Other Users" in which there are some users with access to what I'm guessing is other tables. Now I would like to get data from one of those tables (I can read them manually in SQL Developer, so it's not a access problem or anything). Does anyone have any idea how I shall do that?
The account that you use in SQL Developer has at least read privilges to tables in another schema (owned by another user). You can access these tables by prefixing the table name with the schema name. In Hibernate you'll have to define the non-default-schema in the mapping.

creating a view of tables of a different database

Is it possible to create a view in a database A of tables of another database B? If possible, can somebody please help me, I'm totally clueless.
Of course, just use a database link. So, your view would be:
create or replace view my_view as
select some_columns
from my_table#the_other_database
Beware though it's not always that efficient and you may have some problems with queries doing things you don't expect. If there's any volume to the data you're trying to select it might be worth using a materialized view instead to take data cross server. Then you can select data from the server you're on currently, which'll probably be a lot quicker.

LINQ across multiple databases

I've got two tables that need to be joined via LINQ, but they live in different databases. Right now I'm returning the results of one table, then looping through and retrieving the results of the other, which as you can guess isn't terribly efficient. Is there any way to get them into a single LINQ statement? Is there any other way to construct this to avoid the looping? I'm just looking for ideas, in case I'm overlooking something.
Note that I can't alter the databases, i.e. I can't create a view in one that references the other. Something I haven't tried yet is creating views in a third database that references both tables. Any ideas welcome.
You can do this, even across servers, as long as you can access one database from the other. That is, if it's possible to write a SQL statement against ServerA.DatabaseA that accesses ServerB.DatabaseB.schema.TableWhatever, then you can do the same thing in LINQ.
To do it, you'll need to edit the .dbml file by hand. You can do this in VS 2008 easily like this: Right-click, choose Open With..., and select XML Editor.
Look at the Connection element, which should be at the top of the file. What you need to do is provide an explicit database name (and server name, if different) for tables not in the database pointed to by that connection string.
The opening tag for a Table element in your .dbml looks like this:
<Table Name="dbo.Customers" Member="Customers">
What you need to do is, for any table not in the connection string's database, change that Name attribute to something like one of these:
<Table Name="SomeOtherDatabase.dbo.Customers" Member="Customers">
<Table Name="SomeOtherServer.SomeOtherDatabase.dbo.Customers" Member="Customers">
If you run into problems, make sure the other database (or server) is really accessible from your original database (or server). In SQL Server Management Studio, try writing a small SQL statement running against your original database that does something like this:
SELECT SomeColumn
FROM OtherServer.OtherDatabase.dbo.SomeTable
If that doesn't work, make sure you have a user or login with access to both databases with the same password. It should, of course, be the same as the one used in your .dbml's connection string.
Create a proc/view in your database.
Given your conditions, I don't think you can do this in one Linq statement. But you can join the results of your L2S queries into a Linq to Objects query.

Resources