MySQL Connector SQL Query using LIKE - python-3.x

I have two sets of similar codes that gives different output. The first example does not return any output but the second example returns a output using the same search input.
First Example:
sql = "SELECT accessionID, title, ISBN, publisher, publicationYear FROM Books WHERE %s LIKE %s";
cursor.execute(sql,(col, "%" + values + "%",))
Second Example:
sql = "SELECT accessionID, title, ISBN, publisher, publicationYear FROM Books WHERE title LIKE %s";
cursor.execute(sql,("%" + values + "%",))
The codes that I am trying to code out is that WHERE is dynamic that depends on which text field user searches on. For example, if a user searches something on the title text box, it will only look into Title.
Another way I could think of is to use If conditions to hardcode, but it only works for the first If conditions and subsequent one does not work.
My question is how to make the SQL line dynamic (using first example) in the sense that I can do two %s in the SQL query line and still get the same output?

Related

Update multiple column with bind variable using cx_Oracle.executemany()

I have been trying to update some columns of a database table using cx_Oracle in Python. I created a list named check_to_process which is a result of another sql query. I am creating log_msg in the program based on success or failure and want to update same in the table only for records in check_to_process list. When I update the table without using bind variable <MESSAGE = %s>, it works fine. But when I try to use bind variable to update the columns it gives me error :
cursor.executemany("UPDATE apps.SLCAP_CITI_PAYMENT_BATCH SET MESSAGE = %s, "
TypeError: an integer is required (got type str)
Below is the code, I am using:
import cx_Oracle
connection = cx_Oracle.connect(user=os.environ['ORA_DB_USR'], password=os.environ['ORA_DB_PWD'], dsn=os.environ['ORA_DSN'])
cursor = connection.cursor()
check_to_process = ['ACHRMUS-20-OCT-2021 00:12:57', 'ACHRMUS-12-OCT-2021 16:12:01']
placeholders = ','.join(":x%d" % i for i,_ in enumerate(check_to_process))
log_msg = 'Success'
cursor.executemany("UPDATE apps.SLCAP_CITI_PAYMENT_BATCH SET MESSAGE = %s, "
"PAYMENT_FILE_CREATED_FLAG='N' "
"WHERE PAYMENT_BATCH_NAME = :1",
[(i,) for i in check_to_process], log_msg, arraydmlrowcounts=True)
Many thanks for suggestions and insights!
Your code has an odd mix of string substitution (the %s) and bind variable placeholders (the :1). And odd code that creates bind variable placeholders that aren't used. Passing log_msg the way you do isn't going to work, since executemany() syntax doesn't support string substitution.
You probably want to use some kind of IN list, as shown in the cx_Oracle documentation Binding Multiple Values to a SQL WHERE IN Clause. Various solutions are shown there, depending on the number of values and frequency that the statement will be re-executed.
Use only bind variables. You should be able to use execute() instead of executemany(). Effectively you would do:
cursor.execute("""UPDATE apps.SLCAP_CITI_PAYMENT_BATCH
SET MESSAGE = :1
WHERE PAYMENT_BATCH_NAME IN (something goes here - see the doc)""",
bind_values)
The bottom line is: read the documentation and review examples like batch_errors.py. If you still have problems, refine your question, correct it, and add more detail.

Using sql string as sql statement in odbc power query in excel

I am looking to use a string that takes in some parameters from my cells and use it as my sql statement like so:
" select * from table where " & data_from_cells & " group by ...;"
store it as sqlstring
let
mystring = sqlstring,
myQuery = Odbc.Query("driver={Oracle in etc etc etc", mystring)
and I run into this error
Formula.Firewall: Query '...' (step 'myQuery') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
now apparently I can't combine external queries and another query -- but I am only using passed-on parameters from Excel for my sql string? I am hoping to use WITH keyword as well to make nested queries using parameters but it doesn't even let me combine values from excel with an sql statement..
to be clear, the data_from_cells was transformed and formatted as a string.
When queries that do stuff are called by other queries that do other stuff, sometimes you can get firewall issues.
The way to get around that is for everything to be done in a single query.
The way to get around that without ending up with horrible code is to change your called queries from returning the result to functions that return the result.
For sqlstring:
() => " select * from table where " & data_from_cells & " group by ...;" // returns a function that gets the query string when called
Then your "myQuery" query can be
let
mystring = sqlstring(), //note the parentheses!
myQuery = Odbc.Query("driver={Oracle in etc etc etc", mystring)

How to remove all characters before a specific character in Cognos Report Studio 10.2

I have columns with different company names. In front of each company name there is a Company_ID. After the Company_ID a specific character = _ divides the ID from the Name. For example i have
111_Mercedes
11B4324_Apple
38A_Google
A1ZH8_Airline
I would like to remove all characters including the specific character.
Result should be
Mercedes
Apple
Google
Airline
Thanks in advance
If this is all in one data item and you need a pattern removed, try this:
As an example, 111_Mercedes 11B4324_Apple 38A_Google
The name starts with _ and ends with a space
Because of this, we can use the replace function to set up the process in two steps
1) Wrap the undesired portion in brackets
Sql would look like this
select
concat('<',replace(
replace('111_Mercedes 11B4324_Apple 38A_Google',' ','<')
,'_','>'))
FROM sysibm.sysdummy1
The result would look like
<111>Mercedes<11B4324>Apple<38A>Google
2) Then remove the content in the brackets
Sql would look like this:
Select trim(REGEXP_REPLACE(
'<111>Mercedes<11B4324>Apple<38A>Google'
, '<(.*?)>',' ',1,0,'c'))
FROM sysibm.sysdummy1
The result would look like this
Mercedes Apple Google
For Cognos try to use the functions in the data item definitions
BracketCompany = concat('<',replace(replace([Company ID],' ','<'),'_','>'))
Then another data item over this, to remove the content within the brackets
FinalCompany = trim(REGEXP_REPLACE([BracketCompany], '<(.*?)>',' ',1,0,'c'))

Problem searching MySQL table using MATCH AGAINST

I have a MySQL table containing event data.
On this table, I have a FULLTEXT index, incorporating event_title,event_summary,event_details of types varchar,text,text respectively.
Examples of titles include: "Connections Count", "First Aid", "Health & Safety".
I can search the table as follows:
SELECT * FROM events WHERE MATCH (event_title,event_summary,event_details) AGAINST ('connections');
Which returns the events named "Connections Count" no problem.
However, no matter what I try, I get an empty result set when running the following queries:
SELECT * FROM events WHERE MATCH (event_title,event_summary,event_details) AGAINST ('first aid');
SELECT * FROM events WHERE MATCH (event_title,event_summary,event_details) AGAINST ('first');
SELECT * FROM events WHERE MATCH (event_title,event_summary,event_details) AGAINST ('aid');
I tried renaming an event to "Rich Aid" and could search for that just fine. Also, "First Rich" works great too.
Any ideas of why this is happening or how to fix it would be great!
Thanks for your time.
Rich
"first" is a "stopword" and by default words below 4 caracters are not matched unless you specify ft_min_word_len value.

MYSQL: Using GROUP BY with string literals

I have the following table with these columns:
shortName, fullName, ChangelistCount
Is there a way to group them by a string literal within their fullName? The fullname represents file directories, so I would like to display results for certain parent folders instead of the individual files.
I tried something along the lines of:
GROUP BY fullName like "%/testFolder/%" AND fullName like "%/testFolder2/%"
However it only really groups by the first match....
Thanks!
Perhaps you want something like:
GROUP BY IF(fullName LIKE '%/testfolder/%', 1, IF(fullName LIKE '%/testfolder2/%', 2, 3))
The key idea to understand is that an expression like fullName LIKE foo AND fullName LIKE bar is that the entire expression will necessarily evaluate to either TRUE or FALSE, so you can only get two total groups out of that.
Using an IF expression to return one of several different values will let you get more groups.
Keep in mind that this will not be particularly fast. If you have a very large dataset, you should explore other ways of storing the data that will not require LIKE comparisons to do the grouping.
You'd have to use a subquery to derive the column values you'd like to ultimately group on:
FROM (SELECT SUBSTR(fullname, ?)AS derived_column
FROM YOUR_TABLE ) x
GROUP BY x.derived_column
Either use when/then conditions or Have another temporary table containing all the matches you wish to find and group. Sample from my database.
Here I wanted to group all users based on their cities which was inside address field.
SELECT ut.* , c.city, ua.*
FROM `user_tracking` AS ut
LEFT JOIN cities AS c ON ut.place_name LIKE CONCAT( "%", c.city, "%" )
LEFT JOIN users_auth AS ua ON ua.id = ut.user_id

Resources