Query table with compound primary keys - sql

I'm using pyodbc to connect to a machine database, and query a number of tables in that database using
pandas.read_sql(tbl,cnxn), where tbl = "SELECT * FROM TABLE", cnxn is pyodbc.connect('DSN=DATASOURCE;UID=USERID;PWD=PASSWORD').
It works on most tables, but some tables return:
DatabaseError: Execution failed on sql 'SELECT * FROM TABLE': ('42S02', '[42S02] [Microsoft][ODBC driver for Oracle][Oracle]ORA-00942: table or view does not exist (942) (SQLExecDirectW)')
These tables that return an error, when opened in MS Access, have multiple columns with a key icon on the left when opened in design view (thus a compound primary key, made up from multiple columns).
Is this is the reason I'm having the error described above? How can I solve this?
Edit: as shown in this screenshot, there are multiple columns marked as making up the primary key in design view:
Edit2:Thanks for the feedbacks. After checking ODBC Data Source Administrator window, this data source is on 32-bit platform, and its driver is Microsoft ODBC for Oracle.
I don't think table's name is the issue, because other tables worked and they have the same naming convention (table name is in this format NAME_OF_THE_TABLE). Trying to avoid showing the table name because working on a company project.
I did research the concept of primary key and realized that there can only be one for a table, but as shown in the screenshot attached, there are a five fields shows a key icon on the left.

Before anything, understand MS Access is a unique, GUI tool that maintains its own default database, JET/ACE Engine, but can connect to other databases as well including Oracle, SQL Server, Postgres, etc. via OLEDB/ODBC connections. Essentially, both MS Access and Python are doing the same thing: make an ODBC connection to Oracle (the actual backend database).
Because all linked tables connect fine in MS Access, try matching connections and queries in Python. Likely, the issue involves table names, schema connection, or user access.
Table Name: Your table contains misspellings or reserved words, or a mix of upper or lower cases as defined in their CREATE TABLE setup causing case sensitivity, so Table as defined with CREATE TABLE "Table" is not the same as TABLE. For this reason, use the exact name in the MS Access linked table and wrap with double quotes.
pandas.read_sql('SELECT * FROM "Table"', cnxn)
(Do note: double quotes in SQL is entirely different meaning than double quotes in Python and are not interchangeable with single quotes.)
Connected Schema/User: Incorrect schema. Because schemas in Oracle are more or less users, you may have multiple connections for your MS Access linked tables. Though they all point to same database server with same ODBC driver, the user differs each with different underlying tables. To resolve, match the Python ODBC connection with the MS Access ODBC connection:
You can locate the MS Access connection string under: Table Design (from Navigation Pane) > Property Sheet (from Ribbon) > Description. Use this in the pyodbc.connect(...) call. Likely only the uid and pwd would differ if working across schemas.
Unprivileged User: The connected user does not have select privilege on that table.

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"

Query across two instances

I have one Oracle Instance which homes a number of different Databases, I would like to query across all instances as some of the other database contain related information. How do I setup a query to connect to more that one instance as part of my SELECT statement..
I'm using Oracle SQL Developer if that helps.
Prior to Oracle 12.1 the relationship between Oracle Instances and Oracle Databases was 1 to 1. A single instance could house at most 1 database, though a single server could host multiple instances. However, a single database would have multiple schemas each of which could singly or cooperatively host 1 or more database applications.
Access from one Oracle Instance to another is possible via database links. Database links may be either public or private and may be created with commands similar to this (other options exist):
CREATE [PUBLIC] DATABASE LINK LINK_NAME
CONNECT TO SOME_SCHEMA
IDENTIFIED BY SOME_PASSWORD
USING 'SOME_SERVICE_NAME';
Such a DB Link would be used to reference DB objects in the remote instance by appending the link name to the object reference with an at (#) sign, for example:
SELECT * FROM [SCHEMA.]TABLE_NAME#LINK_NAME;
The above select would return data provided the remote schema associated with the DB link (SOME_SCHEMA in the above create db link statement) has sufficient privileges to select from the referenced remote schema.

Query table from another ORACLE database

I have two different data base, one is DEVORADB which i use for development, and another one is UATORADB which tester use for testing. UATORADB have the most updated data which is not in development. I want to query tables from UATORADB database in DEVORADB. I was writing in DEVORADB in such a way but not getting the result:
SELECT * FROM TABLE_NAME#UATDEVORADB.
For Oracle,
CREATE DATABASE LINK ...
e.g.
With a database link created and tested, you can do a query (of the style you showed) to retrieve rows from a remote database.
Reference: http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_5005.htm#SQLRF01205
FOLLOWUP
NOTE: In Oracle, the term "database" refers to the datafiles and logfiles associated with an Oracle "instance". To retrieve data from a second "database" means you need a second connection to the other database. Oracle provides a facility called a "database link". That allows a session(connection) to one database instance to connect to another database instance. (Without this facility, a client would need to create two separate connections, and would need to query the two databases separately.)
If this question is regarding querying from two separate "schemas" within the same database, as long as the user has sufficient privileges on objects in the second schema, the identifier can be qualified with the name of the schema, e.g.
SELECT * FROM UATDEVORADB.TABLE_NAME
To access data on a separate database, a database link can be used...
CREATE DATABASE LINK UADEVORADB
CONNECT TO user
IDENTIFIED BY password
USING 'uadevoradb' ;
(This will require an appropriate matching entry in the tnsnames.ora file on the Oracle server, or the oracle names server, or the connection details can be spelled out in place of a tnsnames.ora entry, something like:
CREATE DATABASE LINK UADEVORADB
CONNECT TO user IDENTIFIED BY password
USING '(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=uadevorahost1)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=uadevoradb.domaindb)))'
If the "user" specified in the database link differs from the "owner" of the table on the remote system, and there's no synonym that references the table, the table identifier will need to be qualified with the owner...
SELECT * FROM OWNER.TABLE_NAME#UADEVORADB ;

Access Pass Through & Access table

I need to use a pass through query using an ODBC connection, however I need to further refine the SQL using another tables within the same Access database.
How do I reference the Access table? Access keeps thinking I am looking for a table via the ODBC connection rather than the database itself.
First, you create a Linked Table in access, using the ODBC connection. Then, you just write a query against the Access database using whatever name you give your Linked Table, and the names of the access tables.
Be warned: if the linked table contains a large number of rows, Linked Tables can be very inefficient.

Why would my Access 2007 query suddenly become not updateable?

I have a query in Access 2007. It's worked fine for months, but I'm suddenly getting a "the recordset is not updateable" error. Thinking an error must have been caused by a recent change, I went back to archived versions (that definitley worked) - they're all chucking out the same error. The table itself is updatable; indeed, another query on the same table works just fine. What could have suddenly happened to break my query? Code follows:
SELECT Prospects.Company, Contactnames.*, IIf([Prospects]![Key Contact]=[ContactID],True,False) AS [Key Contact], Prospects.Status
FROM Contactnames INNER JOIN Prospects ON Contactnames.CompanyID=Prospects.ID
WHERE (((Prospects.Status) Not Like "Duplicate"));
Any help would be greatly appreciated. Thanks, Oli.
If you are using linked ODBC tables, you need to include the primary key field(s) from all tables in the query if you want the query to be updateable. Here are some potential "gotchas":
Access may not recognize the primary key fields correctly in a linked ODBC table; often (always?) Access picks the first unique index it finds for a table (based on alphabetical order of index name) and assumes that index is the primary key
adding replication to tables in MS SQL Server (and perhaps other RDBMS's) will add a GUID column with a unique index; along with the above point, this can cause Access to think your linked tables have different primary keys than they really do
Changes made to the design of ODBC linked tables are not automatically reflected in Access; linked ODBC tables can be refreshed via Tools --> Database Utilities --> Linked Table Manager... (among other ways)
The likely reason is that it's not the query that has changed, but the database.
Check that the database file hasn't been write protected. That would cause that error message.