How to get information about an SQL Select statement - sql

I am wondering if it is possible to get the real name of the tables/fields from which each field in a select statement comes from.
Lets say you have two tables, Creditors and Debtors both have the fields Code, Name and Phone.
If a user enters the following sql statement:
SELECT Code AS CustomerCode, Name AS CustomerName, Phone AS ContactNumber FROM Debtors.
This will result in SQL server returning field names CustomerCode, CustomerName and ContactNumber.
Is it possible to get from the SQL server some sort of meta data that maps each field to its real name and the table it comes from?
Programmically, given an SQL select statement, I want to be able to determine the real name of each field and the real name of the tables they come from.
I don't want to parse the SQL myself so I thought that there might be away to send the statement to the sql server and get back this information without the row data.
What we are trying to do is implement table/field level security. A user can enter an sql statement to select fields from a table or across multiple tables (using joins) and have the results displayed in a table. The fields get added dynamically to a grid control but only the ones that the user is allowed to see.
If the user joins multiple tables how do we know programmically which fields come from which table? the problem gets worse if they use aliases in the SQL.
Currently this is working on a legacy in house built sql engine (that uses a proprietary database) which can return all of the required table/field information without the row data so part of the applications security model is built around this. However moving this application to something like SQL server might prove difficult if we can't get this to work.
Besides Sql server, do any other sql databases support this type of functionality?

To the best of my knowledge, you cannot get that information.
You can probably handle your problem in many databases, however, by using GRANT / REVOKE security in the database itself. Assuming that users are logging into the database itself (not just your application), many DBMSes allow you to GRANT SELECT privileges on restricted columns from a table. Using that technique, it will not fool the server if the user specifies ALIASes for columns.
A quick google indicates that at least PostgreSQL, SQL Server, and Oracle offer column level GRANT SELECT protection based on userid.
Interesting question, by the way.

No. The whole point is you should only know the name presented to you and not where it came from.
The way to solve your problem is to remove all access from tables and only grant access through views with appropriate access permissions.

Related

Join MS Access Table to Oracle table

I'm playing around with a table in an MS Access database. The table has a primary key of CLIENT_NUMBER. My corporation maintains an Oracle database that has a table which contains clients contact information (address, phone numbers, emails, etc). It also has the CLIENT_NUMBER field. I got to thinking that maybe I can join the 2 tables from the different databases and run some queries. I dug around on the net and I couldn't really find any reference, so I think this is a long shot and a silly question, but is that possible? Maybe through a DB link or something? For reference, I use SQL Developer 3.2.xx for sql developing.
I would copy the table in oracle to Access using what's called a sqlpassthrough query in Access. linked tables to oracle in my experience, perform very poorly, and if you are also thinking about joining to a local table in Access, probably much worse.
Passthrough queries are very quick since Access simply just sends the query for execution to the target server/database based on the connection you identify for the passthrough query, hence the name "pass-through".
The driver in the connect string may not work for you, and it may need more info depending on how things are setup in your environment, so you will have to work that out.
'creates the passthrough query to oracle
With CurrentDb.CreateQueryDef("qOracleConn")
.Connect = "ODBC;Driver={Microsoft ODBC for Oracle};Server=oracleservername;Uid=oracledbusername;Pwd=oracledbpassword;"
.sql = "SELECT * FROM tableinoracle"
End With
'creates the local table in access
CurrentDb.Execute "SELECT * INTO OracleClients FROM qOracleConn"

Impala Show Tables

I know in Impala (and other databases) I can run both of the following:
SHOW DATABASES
SHOW TABLES
I also know I can add optional LIKE or IN arguments e.g. to show me all the tables in database Bananas I could write:
SHOW TABLES IN Bananas
What I really want to know is a way of returning all the tables in the databases without having to recurse through (also showing database name and table name in separate fields.
I'll be running this via impala shell so I'd have to first return back all the database names and then produce a script line per database to give me the tables.
It's not a problem to do this as such, I just can't help wondering there must be a better way to end up with:
Unfortunately not yet. Impala will eventually support this by exposing tables for schema metadata (e.g. ANSI INFORMATION_SCHEMA), and IMPALA-1761 tracks that feature request.

Oracle Database Users in synced database

Ok so I have a little problem...
In my project we have a Oracle SQL Server. In the database I have access to some of an other users tables:
Tables:
|-bla
|-bla
Users:
|-otherUser (let's just call him that)
|-Tables:
|-aTable
In Oracle, to access the aTable table I use SELECT * FROM otherUser.aTable
Now, we also have a MS SQL CE database to which I sync the data from the OracleDB using the MS Sync f/w. And in the CE db - after sync - I get a table otherUser.aTable. This sounds good, so even though the CE doesn't have the User concept it just adds the same table.
BUT the problem is that when calling the same SQL query on CE as on Oracle I get a The table name is not valid error. Instead if I want to get the content of the table, the two ways that I have found to work is surrounding the otherUser.aTable with either [] or "".
However neither of them seem to work with Oracle. The [] seem to be an illegal name, and the "" seem to search for a table called just that (not an other user).
So why don't I just use the one way on Oracle and the other on CE? well I also use NHibernate as a ORM and it kind of needs the same table name for both the databases...
Is there a third way to encapsulate the table name that works with users in Oracle and just works in CE? or do you have any other ways to fix this issue?
I have no experience with MS SQL, but it seems like a problem that might be solved with synonyms on Oracle side.
Try to create synonym "otherUser.aTable" for otherUser.aTable in Oracle.

How can I use two datasources in a CFQUERY?

I am using ColdFusion 9.1.
I need to use two different datasources in some of my queries. I know it can be done because I see other code that uses two different datasources and it works fine.
I've tried lots of combinations but can't get anything to work, but I know that both of my datasources are working properly.
I have a default database set up in the THIS scope. The default is "DatasourceOne".
<cfquery>
SELECT UserID
FROM DatasourceOne.TableOne IN (SELECT Userid FROM DatasourceTwo.TableTwo )
</cfquery
What are the rules or guidelines about using multiple datasources?
CLARIFICATION
I should have originally asked how I could use two database (not datasources) in a single query. I am sure your answers would have been different. We do have both databases set up as datasources though and I was a little confused myself.
Depending on your database, if the second database is on the same server (or is defined as a linked server) and the user in the datasource has permission, you can usually reference the other database.
SELECT * FROM myTable
WHERE myField IN
(SELECT otherField FROM otherDatabase.dbo.tableName)
You can't talk to two CF (JDBC) datasources in a single CFQUERY. What you can do:
Use two databases on the same datasource. For example, if you have a SQL Server instance with two database you can run a query through the JDBC connection that talks to both databases. This looks like what you're describing in your question. Here's a more thorough explanation.
Use Queries of Queries. Pull your data from the two database individually and join the results using a QoQ in your CFC or page.
ColdFusion can only talk to one data*source* at a time in a given query. However, if you need to talk to more than one data*base* on the same server, you can do that by explicitly giving the full paths to the databases, tables, and columns you need to access or join together. Also note that the user that the data*source* in ColdFusion is configured to use must have access to both databases in order for this to work.

SQL Server: is it possible to get data from another SQL server without setting linked server?

I need to do the following query (for example):
SELECT c1.CustomerName FROM Customer as c1
INNER JOIN [ExternalServer].[Database].[dbo].[Customer] as c2
ON c2.RefId = c1.RefId
For some security reason my client doesn't allow me to create a linked server. The user under whom I execute this query has access to both tables. Is it possible to make it work without using linked server? Thanks.
You could use OPENROWSET, which'll require the connection info, username & password...
While I understand that the client believes that having an always-on connection to their data is risky, that's why you lock down the account. OPENROWSET means including the connection info in plain text.
'Linked Server' is a very specific thing -- basically, a permanent connection between servers. I can think of all sorts of reasons not to want that, while at the same time having no problem with folks writing queries that combine data from the two different data sources.
Anyway, depending on your requirement -- if this is just for ad hoc querying, OPENROWSET is good if inside of SQL-Server, or if you want to do this in MS Access, just link to the two tables, and your Access query won't care that one comes from one server, and one comes from another.
Alternatively, with a web or windows front-end, you could indpendently query each table into a data object, and then build a separate query on top of that.
Http Endpoints...
WebServices...
There's a million ways. I wouldn't be so quick to assume, as #Lasse suggests, that any form of 'linking' this data together would make you some kind of rougue data linker.