Parameter for column / table names in SQL query in Pentaho CDE dashboard - jdbc

I'm trying to use parameters for column and table name to SQL query over JNDY, which doesn't work, while parameters for values work fine.
I defined 3 simple parameter components with default values:
paramTable = 'dummyTable'
paramColumn = 'dummyColumn'
paramValue = 'dummyValue'
Then I defined an SQL query over JNDI, that looks like:
select * from ${paramTable} where ${paramColumn} = ${paramValue};
... which does not work, because parameter values of paramTable and paramColumn don't seem to apply properly, which causes:
Caused by: java.sql.SQLSyntaxErrorException: ORA-00903: invalid table name
Here are some query modifications, and their results really disappoint me:
select * from dummyTable where dummyColumn = ${paramValue};
-- works fine and delivers 1 row
select * from ${paramTable} where dummyColumn = 'dummyValue';
-- causes 'invalid table name'
select * from dummyTable where ${paramColumn} = 'dummyValue';
-- does not cause any errors, but if I console.log() the result set of the query,
it is empty (1 row is expected though)
Do I miss something?

Related

How do I search for all the columns/field names starting with "XYZ" in Azure Databricks

I would like to do a big search on all field/columns names that contain "XYZ".
I tried below sql but it's giving me an error.
SELECT
table_name
,column_name
FROM information_schema.columns
WHERE column_name like '%account%'
order by table_name, column_name
ERROR states "Table or view not found: information_schema.columns; line 4, pos 5"
information_schema.columns is not supported in Databricks SQL. There are no in-built views available to get the complete details of tables along with columns. There is SHOW TABLES (database needs to be given) and SHOW COLUMNS (table name needs to be given).
You might have to use Pyspark capabilities to get the required result. First use the following code to get the details of all tables and respective columns:
db_tables = spark.sql(f"SHOW TABLES in default")
from pyspark.sql.functions import *
final_df = None
for row in db_tables.collect():
if(final_df is None):
final_df = spark.sql(f"DESCRIBE TABLE {row.database}.{row.tableName}")\
.withColumn('database',lit(f'{row.database}'))\
.withColumn('tablename',lit(f'{row.tableName}'))\
.select('database','tablename','col_name')
else:
final_df = final_df.union(spark.sql(f"DESCRIBE TABLE {row.database}.{row.tableName}")\
.withColumn('database',lit(f'{row.database}'))\
.withColumn('tablename',lit(f'{row.tableName}'))\
.select('database','tablename','col_name'))
#display(final_df)
final_df.createOrReplaceTempView('req')
Create a view and then apply the following query:
%sql
SELECT tablename,col_name FROM req WHERE col_name like '%id%' order by tablename, col_name

Oracle - Update COUNT of rows with specific value

This question has been posted several times but I am not able to get it work. I tried the approach mentioned in Update column to the COUNT of rows for specific values in another column. SQL Server. It gives me SQLException: java.sql.SQLException: ORA-01427: single-row subquery returns more than one row error not sure what I can do.
Below is my problem
UPDATE dataTable
SET ACCX = (select b.cnt
from dataTable a
join
(SELECT Account,
COUNT(1) cnt
FROM dataTable
GROUP BY Account) b
on a.Account=b.Account)
,ACCR = 15481
,ACCF = 3
WHERE ID = 1625
I only have the access & can change to the bold part since rest of the query is generated by the tool I cannot change it & I have to update ACCX column with the count of the value in column Account. Is it possible to do?
Note: - Account column is already populated with values.
You cannot follow that query because it is for sqlserver and NOT oracle. It is simpler in oracle and does not need a join to itself.
This update will set the count for id 1625 only based on number of account numbers in datatable. See demo here;
http://sqlfiddle.com/#!4/d154c/1
update dataTable a
set ACCR = 15481,
ACCF = 3,
a.ACCX = (
select COUNT(*)
from dataTable b
where b.Account=a.Account)
WHERE a.ID = 1625;

How to use SQL query to define table in dbtable?

In JDBC To Other Databases I found the following explanation of dbtable parameter:
The JDBC table that should be read. Note that anything that is valid in a FROM clause of a SQL query can be used. For example, instead of a full table you could also use a subquery in parentheses.
When I use the code:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "mytable"
)
everything works great, but the following:
dbtable "SELECT * FROM mytable"
leads to the error:
What is wrong?
Since dbtable is used as a source for the SELECT statement it has be in a form which would be valid for normal SQL query. If you want to use subquery you should pass a query in parentheses and provide an alias:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "(SELECT * FROM mytable) tmp"
);
It will be passed to the database as:
SELECT * FROM (SELECT * FROM mytable) tmp WHERE 1=0
Code In Scala
val checkQuery = "(SELECT * FROM " + inputTableName + " ORDER BY " + columnName + " DESC LIMIT 1) AS timetable"
val timeStampDf = spark.read.format("jdbc").option("url", url).option("dbtable", checkQuery).load()
Adding an alias is also necessary after the query in parenthesis.

getting Hibernate error when using DBMS_RANDOM.value

I would like to achieve same result as the below query using Hibernate SQL, i.e., I would like to get two random records from the table whose ID is not equal to 300. I am using Hibernate 4.1 and Oracle 11g. I ran the below query on Toad and it gives 2 random records. But, when I try to run the HQL, there is error to do with the usage of "DBMS_RANDOM.value".
SELECT * FROM
( SELECT *
FROM table
where ID != '300'
AND q_ID=125
ORDER BY DBMS_RANDOM.value
)WHERE rownum < 3
;
I tried creating criteria and query, but both give Hibernate errors:
Hibernate Message: Invalid path: 'DBMS_RANDOM.RANDOM' [from com.model.table tab where tab.ID != '33092' ORDER BY DBMS_RANDOM.RANDOM]
and my actual hibernate query is:
Query query = session.createQuery("from table tab where tab.ID != '" +agrmId+"' ORDER BY DBMS_RANDOM.RANDOM").setMaxResults(2);
I also tried ORDER BY rand() and that gives an Oracle error.
Thank you for any help.
I solved the problem by adding a property tag in the hibernate mapping file:
<property name="constVal" formula="DBMS_RANDOM.RANDOM" type="long"/>
and then, in the POJO class, I added a variable with getter and setter methods:
private long constVal;
then, in the DAO class, I added the following query:
Criteria crit1 = session.createCriteria(table.class);
crit1.add(Restrictions.ne("id",300));
crit1.add(Restrictions.eq("quesId",125));
crit1.addOrder(Order.asc("constVal"));
crit1.setMaxResults(2);
and that solved it.

QueryDSL: How to insert or update?

I'm trying to implement https://stackoverflow.com/a/16392399/14731 for a table called "Modules" using QueryDSL. Here is my query:
String newName = "MyModule";
QModules modules = QModules.modules;
BooleanExpression moduleNotExists = session.subQuery().
from(modules).where(modules.name.eq(newName)).notExists();
SimpleSubQuery<String> setModuleName = session.subQuery().
where(moduleNotExists).unique(Expressions.constant(newName));
long moduleId = session.insert(modules).set(modules.name, setModuleName).
executeWithKey(modules.id);
I am expecting this to translate into:
insert into modules(name)
select 'MyModule'
where not exists
(select 1 from modules where modules.name = 'MyModule')
Instead, I am getting:
NULL not allowed for column "NAME"; SQL statement:
insert into MODULES (NAME)
values ((select ?
from dual
where not exists (select 1
from MODULES MODULES
where MODULES.NAME = ?)))
where ? is equal to MyModule.
Why does QueryDSL insert from dual? I am expecting it to omit from altogether.
How do I fix this query?
For the insert into select form use
columns(...).select(...)
But your error suggests that the INSERT clause is valid, but semantically not what you want.
Using InsertClause.set(...) you don't get the conditional insertion you are aiming for.
In other words with
columns(...).select(...)
you map the full result set into an INSERT template and no rows will be inserted for empty result sets, but with
set(...)
you map query results to a single column of an INSERT template and null values will be used for empty results.

Resources