Dynamically maintain a table which has a where clause values in it.? - where-clause

I am planning to dynamically create a where clause using the values stored in an sql table. The table looks something like the below.
Conjuction Attribute Expression Value
EMP_NAME LIKE 'Sam%'
OR DEPT_NO IN (20, 30)
AND SAL >= 3000
Using such table I want to build a procedure/function which gives a full string of where clause dynamically which I want to use in my application.
Basically the above condition should look like below in the output.
(EMP_NAME LIKE 'Sam%' OR DEPT_NO IN (20, 30)) AND SAL >= 3000.
Can you please help me find a solution to get such output using even more complex conditions.
Thank you very much.

Related

How to parameterize IN clause in SQL Query to use in JMETER

I need to parametrize a SQL Query to use in JMETER such that every time it triggers, a random value is picked from the list of values to be used in IN clause.
Parent Query - Select * from Employee where Emp_Id in ( 3,9,11,12,13) and Dept_Name in('HR',IT','Admin','Audit')
Post the Parameterization when i trigger the Query through JDBC Request the request run for different user needs to have random selection made.
Ex:
Query 1 should be like - Select * from Employee where Emp_Id in ( 3,9) and Dept_Name in('HR',IT')
Query 2 should be like - Select * from Employee where Emp_Id in ( 11,12,13) and Dept_Name in('HR',IT','Admin')
I am trying to use CSV Data Set Config but not able to achieve the above output.
First of all I would recommend reconsidering your whole approach because tests needs to be repeatable, if you need to check all the possible combinations of the emp and dept IDs - go for pairwise testing, store the generated queries in the CSV file and parameterize the queries using CSV Data Set Config.
If you still want to make the number of arguments absolutely random you can go for the following approach:
Add User Defined Variables to your Test Plan and define the following variables there:
Emp_Id=3,9,11,12,13
Dept_Name=HR,IT,Admin
Amend your query to include JMeter's __groovy() function like:
Select * from Employee where Emp_Id in (${__groovy(def values = vars.get('Emp_Id').split('\,').collect(); values.shuffle(); values.take(org.apache.commons.lang3.RandomUtils.nextInt(1\,values.size())).join('\,'),)}) and Dept_Name in(${__groovy(def values = vars.get('Dept_Name').split('\,').collect{value -> "'" + value + "'"}; values.shuffle(); values.take(org.apache.commons.lang3.RandomUtils.nextInt(1\,values.size())).join('\,'),)})
Demo:

Querying an Oracle Database with Dynamic Table names

I'm stuck with some poor database design where I have to query tables that are named by date.
The following query works when the table names are hard coded with relevant dates.
SELECT
ajob.ORDER_ID
, ajob.JOB_NAME
, abim.SERVICE_ID
, shist.SERVICE_NAME
FROM
obscuredschema.A190129001_AJOB ajob --hardcoded YYMMDD table name
INNER JOIN obscuredschema.A190129001_ABIMSVC abim --hardcoded YYMMDD table name
ON (ajob.ORDER_ID = abim.ORDER_ID)
INNER JOIN obscuredschema.SERVICE_HIST shist
ON (abim.SERVICE_ID = shist.SERVICE_KEY)
WHERE shist.SERVICE_NAME LIKE '%BIM'
AND shist.BIM_AUTH_ID > 0
;
Noting the two hardcoded table names (along with aliases)
How would I execute this same query using dynamic table names? (There's two)
The code for the dynamic date: TO_CHAR(trunc(sysdate - 7), 'YYMMDD')
If the first table name were a string, here's how I would build it:
'A'||TO_CHAR(trunc(sysdate - 7), 'YYMMDD')||'001_AJOB'
If the second table name were a string, here's how I would build it:
'A'||TO_CHAR(trunc(sysdate - 7), 'YYMMDD')||'001_ABIMSVC'
I don't think you can write a plain SQL query with dynamic table names.
You can write a PL/SQL procedure which uses execute immediate and returns a cursor or something; somebody asked about that just yesterday. If you're just trying to write this query to interact with some data, that might be your best bet.
In addition, you could modify that by turning your PL/SQL procedure into a pipelined function, and then you could call it from a SQL query using TABLE().
If it were me, I'd consider creating a synonym (or a standard view which just selects from the dynamically-named-tables), and scheduling a job to re-create it every time new tables are created. That might be simpler than dealing with pipelined functions.

List the employees whose name starts with 'S' and ends with 'S'?

I know the SQL LIKE statement.
I want to implement SQL LIKE statement in Informatica.
The goal is list all the employees whose name starts with 'S' and ends with 'S'.
select ENAME from EMP where ENAME LIKE ('S%') and ENAME LIKE('%S');
It looks like Informatica does not have a LIKE equivalent available. You can use REG_MATCH and insert in a regular expression that will match for starts with S and ends with S. Example Below:
REG_MATCH(ENAME,'[S^]+\w+[S$]')
RegExr Link: http://regexr.com/3b17b

SQL equivalent of Excel's approximate VLOOKUP (first relevant value) without nested query

I am trying to find an efficient way to select the first relevant value from an existing table, as Excel's VLOOKUP( , , , TRUE) function would. Here is what I have, but if #tableWithData is very large compared to #requiredDates, this code can be very inefficient. I feel like I am missing something. Is there a better way of writing this:
DECLARE #requiredDates TABLE
(requiredDate datetime)
INSERT INTO #requiredDates VALUES ('2014-01-01');
INSERT INTO #requiredDates VALUES ('2014-01-15');
INSERT INTO #requiredDates VALUES ('2014-02-01');
INSERT INTO #requiredDates VALUES ('2014-02-15');
DECLARE #tableWithData TABLE
(respectiveDate datetime,
associatedValue int
)
INSERT INTO #tableWithData VALUES ('2014-01-01', 1);
INSERT INTO #tableWithData VALUES ('2014-02-01', 2);
SELECT
lookupTable.requiredDate,
dataTable.associatedValue
FROM #tableWithData as dataTable RIGHT JOIN
(
/*Create table which maps the requiredDates -> maxDate highest available date */
SELECT
dates.requiredDate,
MAX(data.respectiveDate) as maxDate/*,
data.associatedValue*/
FROM #requiredDates as dates JOIN #tableWithData as data
ON dates.requiredDate >= data.respectiveDate
GROUP BY dates.requiredDate
) as lookupTable
on lookupTable.maxDate = dataTable.respectiveDate
Note: I am using MS Server 2005, but would also appreciate a more generic SQL implementation, if there is one.
In Excel, vlookup() with a value of "TRUE" finds an approximate match. I am finding your query a bit hard to follow, but the following will get the largest value less than or equal to the respectiveDate field:
SELECT dt.associatedValue,
(SELECT TOP 1 rd.requiredDate
FROM dates.requiredDate rd
WHERE rd.requiredDate <= dt.respectiveDate
ORDER BY rd.requiredDate DESC
) as RequiredDate
FROM #tableWithData dt;
This structure for the query will work in all databases, with the caveat that TOP 1 probably needs to be replaced with something else (a limit clause, a fetch first 1 rows only clause, or something else). Of course, temporary tables will not.
In SQL Server, you can also express this using APPLY.
I was looking for a solution to this then realised that for the type of data I had there was a very simple answer and although it does not quite match your problem you might find it useful. Imagine the query you are trying to run is who was the reigning monarch on a given date and you have a table of the reigns of monarchs. In excel you would do a vlookup search on a sorted table of the start or end dates of the reigns but in SQL it is much easier to have separate columns for reign-start and reign-end the query then is as simple as
SELECT * FROM 'monarchs' WHERE reign_start > date AND reign_end < date
As I said this is such a simple query that in some cases it might be worth seeing if the data could be reconfigured to allow it.

Very simple SQL query on varchar fields with sqlite

I created a table with this schema using sqlite3:
CREATE TABLE monitored_files (file_id INTEGER PRIMARY KEY,file_name VARCHAR(32767),original_relative_dir_path VARCHAR(32767),backupped_relative_dir_path VARCHAR(32767),directory_id INTEGER);
now, I would like to get all the records where original_relative_dir_path is exactly equal to '.', without 's. What I did is this:
select * from monitored_files where original_relative_dir_path='.';
The result is no records even if in the table I have just this record:
1|'P9040479.JPG'|'.'|'.'|1
I read on the web and I see no mistakes in my syntax... I also tried using LIKE '.', but still no results. I'm not an expert of SQL so maybe you can see something wrong?
Thanks!
I see no problem with the statement.
I created the table that you described.
Did an INSERT with the same values that you provided.
And did the query, and also queried without a where clause.
No problems encountered, so I suspect that when you execute your selection, you may not be connected to the correct database.