This question already has an answer here:
Escape Variables with Printf
(1 answer)
Closed 3 years ago.
I have an SQL query that looks like this:
SELECT name FROM sessions WHERE name ILIKE 'org_name.%';
but I'm actually interested in replacing 'org_name' with format string (%s).
I was trying to do something like this:
query := fmt.Sprintf("SELECT name FROM sessions WHERE name ILIKE '%s.%'", "org_name2")
but go seems to not like it, since writing %' isn't valid as format string.
I know I can solve it with do it in that way:
orgName := "org_name2"
condition := fmt.Sprintf("%s", orgName) + ".%"
query := fmt.Sprintf("SELECT name FROM sessions WHERE name ILIKE '%s'", condition)
but, I'd rather not, since the variable here is solely the org_name.
Is there a solution for this?
Thanks!
As documented in the fmt package, a literal % can be represented by %% in a printf format string:
query := fmt.Sprintf("SELECT name FROM sessions WHERE name ILIKE '%s.%%'", orgName)
But be aware, you should NEVER, EVER build your SQL queries this way! You are potentially opening yourself for SQL injection attacks. Instead, you should pass parameterized arguments:
query := "SELECT name FROM sessions WHERE name ILIKE ?"
rows, err := db.Query(query, orgName + ".%")
In go it is just fmt.Printf("%s is how you write a %%", "This")
https://play.golang.org/p/RIJKRADYzCk
Related
I've been searching for a method to make this MariaDB prepared statement to be able to run in node.js. The problem here is that the search term "MariaDB prepared statement in node.js" does not return results that I am looking for.
To clarify much further, I have a MariaDB prepared statement like below and I've been using it for most of my customized reports that my employer requested:
SET #columns := NULL;
SET #sql := NULL;
SET #df := '2022-01-07';
SET #dt := CURDATE();
SET #pc := 'barcode IN ("111", "222", "333")';
SELECT GROUP_CONCAT(
CASE WHEN seq=1 THEN
CONCAT('SUM(CASE WHEN barcode="',barcode,'" then sold_qty else 0 END) AS "',
product_name,' \r\n ---- \r\n Sold Qty"')
WHEN seq=2 THEN
CONCAT('SUM(CASE WHEN barcode="',barcode,'" then sales_amt else 0 END) AS "',
product_name,' \r\n ---- \r\n Sales Amt"') END SEPARATOR ', \r\n' ) INTO #columns
FROM products
CROSS JOIN (SELECT 1 seq UNION SELECT 2) s
WHERE barcode IN ("111", "222", "333");
SELECT CONCAT('SELECT sales_date,
',#columns,'
FROM (',
GROUP_CONCAT(
CONCAT(
'
SELECT * FROM ',TABLE_NAME,' WHERE ',#pc) SEPARATOR ' \r\n UNION ALL \r\n'),
') v
WHERE sales_date >= "',#df,'"
AND sales_date < "',#dt,'"
GROUP BY sales_date;') into #sql
FROM information_schema.tables
WHERE table_name LIKE 'sales_tbl%'
AND STR_TO_DATE(CONCAT(RIGHT(TABLE_NAME,6),'01'),'%Y%m%d') >= #df-INTERVAL 1 MONTH;
Basically, I'm generating a pivot query and I'm creating the columns and defining the tables (for the UNION ALL) dynamically. My node.js (or even javascript) knowledge so far is still quite beginner-ish so I attempt to re-create this prepared statement query as-is and obviously failed. I do understand why it's not working though. I've tried multiple search terms to find any question in SO that is related to my issue but I couldn't find one.
The query does pretty well for me so I don't really have any issue with it. It's just that, I'm looking to develop a customizable web report app that everybody in my organization can use.
Here's a fiddle for reference.
After further testing, I can actually use the prepared statement as-is in node.js but it requires me to add multipleStatements: true for the node.js mysql client; which I'm familiar with as I did use this method for my older projects however, it comes to my attention that using this setting is not exactly safe. I have an older question regarding this as well. Even though the web-app I'm building is just for internal usage, I (try to) prevent using unsafe practices.
I need to create a dynamic query based on two string parameters:
description = "This is the description"
comment = "This is the comment"
query = "insert into case(desc, comm) value(description, comment)"
Note:
there might be single quote and double quotes in both description and comment.
How do I use formatted %s to generate the query string?
Thank you very much.
UPDATE:
Thanks to Green Cloak Guy (his/her answer has minors to be corrected), the right query is:
query = f"insert into case(description, comment) value(\'{description}\', \'{comment}\')"
Use an f-string.
query = f"insert into case({description}, {comment}) value({description}, {comment})"
Don't use any type of string formatting to do actual database queries - that leads to you having a SQL Injection problem. Use a database library instead, that properly sanitizes the data.
But if all you need to do is parse some variables into a string, this is more flexible than the % formatting that other languages tend to use (and that's technically still available in python via "some_string %s %s %s" % (str1, str2, str3)")
A possible solution for this question is here:
https://stackoverflow.com/a/6223961/12343395
It will probably work with a lot of work around.
But I have stored my table names in string format and want to call them as needed.
I am using Pandas read_sql_query. So as in params, I am passing, the table name and a few parameters in the WHERE section.
The WHERE section is fine, since the parameters are originally strings. But in the FROM section,
I really want the schema.table as a non-string.
Here is a snippet.
SELECT "rainfall(mm)","tmin(C)","tmax(C)","TimeStamp"
FROM crop_tables[choose_crop][0]
WHERE "District_Name" = %s AND "Season" = %s
ORDER BY "TimeStamp" ASC
where crop_tables[choose_crop][0] is 'sagita_historic.soyabean_daily_analyses' in this case.
But FROM will throw an error since it doesn't accept strings. So in essence, I wish to strip the 'sagita_historic.soyabean_daily_analyses' as a non-string.
Is it possible to do so?
Thank you.
Not sure I fully understand but maybe this will do?
SELECT "rainfall(mm)","tmin(C)","tmax(C)","TimeStamp"
FROM f"{crop_tables[choose_crop][0]}"
WHERE "District_Name" = %s AND "Season" = %s
ORDER BY "TimeStamp" ASC
Is there a nice way to assign a string to a variable when it spans many lines?
The reason for this is I have some large SQL statements (which I want in the pas) but it's annoying like this
var
sql : string;
begin
sql := 'SELECT * ' +
'FROM foo ' +
'WHERE `this`=0';
That is annoying to copy and paste into terminal / another program because I have to remove the ' and ' + etc.
Is there a way to so something like...
var
sql : string;
begin
sql := ""SELECT *
FROM foo
WHERE `this`=0"";
So some way to assign a block of text/string with new lines without having to concat it.
As there is no way of expressing strings in this way in SQL, I normally use the RegEx search and replace available in the Delphi IDE to format strings in the required way.
SELECT *
FROM foo
WHERE `this`=0
This replaces any line with the line enclosed in quotes, followed by + sLineBreak +
sql :=
' SELECT *' + sLineBreak +
' FROM foo' + sLineBreak +
' WHERE `this`=0' + sLineBreak +
I then just tidy up the last line:
sql :=
' SELECT *' + sLineBreak +
' FROM foo' + sLineBreak +
' WHERE `this`=0';
Of course the same can be done with any preceding or trailing text, such as qry.SQL.Add('\0');
Your question is:
Can a Delphi string literal span multiple lines?
The answer is no.
Not that I know of (at least not out of the box). Anyway, you might want to take a look at this:
How to assign a multiline string value without quoting each line?
You could keep the SQL in a component which has a TStrings property like TSQLQuery, but my solution for longer / complex statements is to keep an 'example' copy as a source code comment, which has actual parameters to make tests easier, and keep both version in sync.
If you like the way C# does it (like I do), then don't forget to vote for this QC report:
http://qc.embarcadero.com/wc/qcmain.aspx?d=2012
It suggests to make your example look like this:
var
sql : string;
begin
sql := #'SELECT *
FROM foo
WHERE `this`=0';
If you install GExperts in Delphi, the IDE will automatically insert a '+ after pressing >enter< if you're inside a string and haven't closed it yet.
Download link: http://www.gexperts.org/download.html
I'd like to make a query insert:
INSERT INTO A_TABLE (BLOB_FIELD) VALUES(MY_BLOB_VAL)
but I have only string values in delphi for ex:
procedure INSERT_BLOB_QUERY
var
query:String;
my_blob_val:String;
begin
my_blob_val := 'a blob string to be inserted';
query := 'INSERT INTO A_TABLE (BLOB_FIELD) VALUES(' + my_blob_val + ')';
// to execute a query....
end;
The problem that occours is string to blob conversion.
So how to I insert a string in a interbase blob field???
Like this:
procedure INSERT_BLOB_QUERY;
begin
query.SQL.Text := 'INSERT INTO A_TABLE (BLOB_FIELD) VALUES (:VAL)';
query.ParamByName('VAL').AsString := 'a blob string to be inserted';
end;
Your code doesn't work because you're not passing the string as a parameter, you're passing it as part of the query. If you do that, you obviously need to QUOTE it: the way you're doing it Interbase will try to interpret it as SQL commands, not as a literal string to be inserted in a db column.
None the less, don't go for quoting. It's always better to use parameters, it's safer!