I was trying to get data from two tables in db that I have connected through ODBC. not sure exactly how to do it because I was trying basic queries I learnt in db400.
ODBC CONNECT TO trial;
//-------- Start Multiple Select Statements ------
SQL SELECT *
FROM graphdata.`kbl_one_voice_responsiveness_measured`;
//-------- End Multiple Select Statements ------
/*TARGET TABLE */
LOAD [setup],
'Responsiveness' as Domain,
[sku],
[KPI],
[target]
as [SQL SELECT *
FROM graphdata.`kbl_one_voice_responsiveness_target`;]
AND I'm getting this error
Syntax error
Unexpected token: 'ODBC', expected one of: ',', 'AutoGenerate', 'From', 'From_Field', 'Inline', 'Resident', 'Where', ...
LOAD [setup],
'Responsiveness' as Domain,
[sku],
[KPI],
[target]
as [SQL SELECT *
FROM graphdata.`kbl_one_voice_responsiveness_target`;]
///$tab KBL_Perf
>>>>>>ODBC<<<<<< CONNECT TO trial
please let me know where I'm going wrong
You shouldn't wrap the sql select in []
LOAD
setup,
'Responsiveness' as Domain,
sku,
KPI,
target
;
SQL
SELECT
*
FROM
graphdata.`kbl_one_voice_responsiveness_target`
;
Also there is no need to wrap fields in [] unless they are containing spaces.
Related
I'm running a dag with an insert query. Here is some of the code:
QUERY = '''
INSERT INTO bi.target_skus (skus)
SELECT
distinct od.sku,
FROM
bi.orders as od'''
t1 = MySqlOperator(
sql=QUERY,
mysql_conn_id = MYSQL_CONN_ID,
task_id='target_skus',
dag=dag)
It's giving me the following error:
ERROR - (1142, "INSERT command denied to user 'xyz' for table 'target_skus'")
A few notes:
Devops said my user has permission to make inserts into that table
Select commands work fine
The error message does not include the database name (bi) even though my insert query does.
This looks like a standard MySQL "not enough privileges" error.
Are you sure you can perform INSERTs with your user, regardless of what your DBA is saying? You should test the same operation using another tool (like MySQL Workbench) setting up the connection in the same way you set it up in Airflow, i.e. same user, same password, same default schema.
It looks like a privilege error from the user trying to insert but there is a comma in the insert that can cause problems too:
QUERY = '''
INSERT INTO bi.target_skus (skus)
SELECT
distinct od.sku
FROM
bi.orders as od'''
I am working on a system where I need to create a view.I have two databases
1.CDR_DB
2.EMS_DB
I want to create the view on the EMS_DB using table from CDR_DB. This I am trying to do via dblink.
The dblink is created at the runtime, i.e. DB Name is decided at the time user installs the database, based on the dbname dblink is decided.
My issue is I am trying to create a query like below to create a view from a table which name is decided at run time. Please see below query :
select count(*)
from (SELECT CONCAT('cdr_log#', alias) db_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4 ) db_name;
In this query cdr_log#"db_name" is the runtime table name(db_name get's created at runtime).
When I'm trying to run above query, I'm not getting the desired result. The result of the above query is '1'.
When running only the sub-query from the above query :
SELECT CONCAT('cdr_log#', alias) db_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4;
i'm getting the desired result, i.e. cdr_log#cdrdb01
but when i'm trying to run the full query, getting result as '1'.
Also, when i'm trying to run as
select count(*) from cdr_log#cdrdb01;
I'm getting the result as '24' which is correct.
Expected Result is that I should get the same output similar to the query :
select count(*) from cdr_log#cdrdb01;
---24
But the desired result is coming as '1' using the full query mentioned initially.
Please let me know a way to solve the above problem. I found a way to do it via a procedure, but i'm not sure how can I invoke this procedure.
Can this be done as part of sub query as I have used above?
You're not going to be able to create a view that will dynamically reference an object over a database link unless you do something like create a pipelined table function that builds the SQL dynamically.
If the database link is created and named dynamically at installation time, it would probably make the most sense to create any objects that depend on the database link (such as the view) at installation time too. Dynamic SQL tends to be much harder to write, maintain, and debug than static SQL so it would make sense to minimize the amount of dynamic SQL you need. If you can dynamically create the view at installation time, that's likely the easiest option. Even better than directly referencing the remote object in the view, particularly if there are multiple objects that need to reference the remote object, would probably be to have the view reference a synonym and create the synonym at install time. Something like
create synonym cdr_log_remote
for cdr#<<dblink name>>
create or replace view view_name
as
select *
from cdr_log_remote;
If you don't want to create the synonym/ view at installation time, you'd need to use dynamic SQL to reference the remote object. You can't use dynamic SQL as the SELECT statement in a view so you'd need to do something like have a view reference a pipelined table function that invokes dynamic SQL to call the remote object. That's a fair amount of work but it would look something like this
-- Define an object that has the same set of columns as the remote object
create type typ_cdr_log as object (
col1 number,
col2 varchar2(100)
);
create type tbl_cdr_log as table of typ_cdr_log;
create or replace function getAllCDRLog
return tbl_cdr_log
pipelined
is
l_rows typ_cdr_log;
l_sql varchar(1000);
l_dblink_name varchar(100);
begin
SELECT alias db_name
INTO l_dblink_name
FROM ems_dbs a,
cdr_manager b
WHERE a.db_type = 'CDR'
and a.ems_db_id = b.cdr_db_id
and b.op_state = 4;
l_sql := 'SELECT col1, col2 FROM cdr_log#' || l_dblink_name;
execute immediate l_sql
bulk collect into l_rows;
for i in 1 .. l_rows.count
loop
pipe row( l_rows(i) );
end loop;
return;
end;
create or replace view view_name
as
select *
from table( getAllCDRLog );
Note that this will not be a particularly efficient way to structure things if there are a large number of rows in the remote table since it reads all the rows into memory before starting to return them back to the caller. There are plenty of ways to make the pipelined table function more efficient but they'll tend to make the code more complicated.
I wanted to fetch the currently executing queries in Teradata and when I ran the below SQL and I got the error message as 'Failed 9881 : Function 'MonitorSQLText' called with an invalid number or type of parameters'. I am using TD 14.10
SELECT * FROM TABLE (MonitorSQLText(-1, '*', 0)) AS T2;
Please help me with this query.
MonitorSQLText can only be applied to a single session.
To get info for all sessions you must use MonitorSession(-1, '*', 0), when you do it in a Stored Procedure you can run it as a cursor and process each row.
With the release of dplyr 0.7.0, it is now supposedly easy to connect to Oracle using the odbc package. However, I am running into a problem accessing tables not inside the default schema (for me it is my username). For example, suppose there is the table TEST_TABLE in schema TEST_SCHEMA. Then, example SQL syntax to get data would be: select * from TEST_SCHEMA.TEST_TABLE'.
To do the same in `dplyr, I am trying the following:
# make database connection using odbc: [here's a guide][1]
oracle_con <- DBI::dbConnect(odbc::odbc(), "DB")
# attempt to get table data
tbl(oracle_con, 'TEST_SCHEMA.TEST_TABLE')
Now, this leads to an error message:
Error: <SQL> 'SELECT *
FROM ("TEST_SCHEMA.TEST_TABLE") "zzz12"
WHERE (0 = 1)'
nanodbc/nanodbc.cpp:1587: 42S02: [Oracle][ODBC][Ora]ORA-00942: table or view does not exist
I think the problem here is the double quotation marks, as:
DBI::dbGetQuery(oracle_con, "select * from (TEST_SCHEMA.TEST_TABLE) where rownum < 100;")
works fine.
I struggled with this for a while until I found the solution at the bottom of the introduction to dbplyr. The correct syntax to specify the schema and table combo is:
tbl(oracle_con, in_schema('TEST_SCHEMA', 'TEST_TABLE'))
As an aside, I think the issue with quotation marks is lodged here: https://github.com/tidyverse/dplyr/issues/3080
There are also the following alternate work-arounds that may be suitable depending on what you wish to do. Since the connection used DBI, one can alter the schema via:
DBI::dbSendQuery(oracle_con, "alter session set current_schema = TEST_SCHEMA")
after which tbl(oracle_con, 'TEST_TABLE') will work.
Or, if you have create view privileges, you can create a "shortcut" in your default schema to any table you are interested in:
DBI::dbSendQuery(oracle_con, "CREATE VIEW TEST_TABLE AS SELECT *
FROM TEST_SCHEMA.TEST_TABLE")
Note that the latter may be more suitable for applications where you wish to copy local data to the database for a join, but do not have write access to the table's original schema.
I know that to find all the fields of a table I should use something like
sqlplus > desc testtable;
This lists all the fields of a table (here testtable)
But now, I have a list of tables in my database.
What is the way through which I can get the fields of all tables
in a given database using sqlplus?
I tried
sqlplus > desc <Databasename>; which didnot work.
Someone told me to use
sqlplus > select * from INFORMATION_SCHEMA.TABLES ; //gives error.
SQLPLUS > SELECT * FROM INFORMATION_SCHEMA.COLUMNS; //gives some error.
(At the bottom line, I am trying to get the database schema.)
I don't believe that the information_schema tables you can find in other dbs (SQL Server, PostGres, MySQL, etc) is in Oracle. I use to use the ALL_TAB_COLUMNS table to get at that type of information....maybe another alternative.
Link: ALL_TAB_COLUMNS