Escaping percent signs in Lua Sqlite3 Prepare Statement - sqlite

I have a statement:
(db is a sqlite3 instance)
local stmt = db:prepare("SELECT id, name FROM table WHERE name LIKE '%?%'")
if stmt:bind_values("test") == sqlite3.OK then
....
end
However, I get this error:
Incorrect number of parameters to bind (1 given, 0 to bind)
It seems it is not seeing the ? as a parameter. I have tried all kinds of escaping from %% for the percent signs to \ and \\ and beyond...driving me crazy.
Anyone know how to fix this? Thank you!

You can't put parameters inside quotes:
correct: SELECT ... WHERE foo = ?
incorrect: SELECT ... WHERE foo = '?'
With the quotes, it's just a string that contains a question mark. Without the quotes, it's a placeholder.
You'll have to build up the LIKE in pieces, e.g.
... WHERE foo LIKE '%' || ? || '%'

Related

How do safely I add a raw string to a query?

My SQLite query :
let data = db.getAllRows(sql"""
SELECT name, source, uploaded_at, canonical_url, size
FROM table
WHERE name like ?
ORDER BY ? DESC
LIMIT ?
OFFSET ?
""", &"%{query}%", order, limit, offset)
Nim adds single quotes to any string replacing ?. I can manually build the SQL string and then use sql(string), but the input then isn't escaped. Is there some other token apart from ? that does not add '?
To answer your title question: "How to safely add a raw string to a query", you can use dbQuote:
import db_sqlite
let
a = "unes'caped %' string"
b = "my prefix ->"
c = "<- my suffix"
d = b & dbQuote(a) & c
echo d
This will print my prefix ->'unes''caped %'' string'<- my suffix, adding quotes before/after and escaping any ones inside. This string is presumably safe to pass as an sql statement. You should get the same result as if you had used ? with extra parameters.

how do code a sql statement replacing all x'BF' with x'00' for a certain data field that contains the ascii downside ? to replace it with null x'00'

how do I code this properly to work in Oracle SQL :
update table_name
set field_name =
replace(field_name, x'BF', x'00')
where condition expression ;
Not sure how to code the replace all occurrence of hex 'BF' with null value hex'00' contained in data field field_name.
You can use the unistr() function to provide a Unicode character. e.g.:
update table_name
set field_name = replace(field_name, unistr('\00bf'))
where condition expression ;
which would remove the ¿ character completely; or to replace it with a null character:
set field_name = replace(field_name, unistr('\00bf'), unistr('\0000'))
though I suspect sticking a null in there will confuse things even more later, when some other system tries to read that text and stops at the null.
Quick demo:
with t (str) as (
select 'A ¿ char' from dual
)
select str,
replace(str, unistr('\00bf')) as removed,
replace(str, unistr('\00bf'), unistr('\0000')) as replaced,
dump(replace(str, unistr('\00bf')), 16) as removed_hex,
dump(replace(str, unistr('\00bf'), unistr('\0000')), 16) as replaced_hex
from t;
STR REMOVED REPLACED REMOVED_HEX REPLACED_HEX
--------- --------- --------- ----------------------------------- -----------------------------------
A ¿ char A char A char Typ=1 Len=7: 41,20,20,63,68,61,72 Typ=1 Len=8: 41,20,0,20,63,68,61,72
(Just as an example of the problems you'll have - because of the null I couldn't copy and paste that from SQL Developer, and had to switch to SQL*Plus...)
The first dump shows the two spaces (hex 20) next to each other; the second shows a null character between them.

how to search for a particular string in the given string in oracle

I have a string with value as '12A,12B,12C,13,14'.
I want to check whether '2A' is available in the above string.
while trying my value '2A' checks in 12A and returns as matched.
Please give me a solution for this.
You can do something like this:
select * from table where ',' || col || ',' like '%,2A,%';
Commas are concatenated to the column to cover the cases where the element is present at the start or end of the string.

How do I add opening and closing brackets to the beginning and end of the data string in Sqlite

I have a column of text in sqlite that I have to select and add brackets to the beginning and end of each string of data. EG. column has "hello" I need to select it, adding brackets so it looks like "(hello)"
I have done this before in Sqlite, but can't remember how I did it. Any ideas would be really appreciated. I am sure it will be pretty simple.
Use || to concatenate strings:
SELECT '(' || 'hello' || ')';
SELECT '(' || column_name || ')' FROM table_name WHERE condition;

PL-SQL bind variables in TCL

Could some one explain in the following TCL source code:
set sql "SELECT PROD.KEY || ' {' || PARAMETERS || '}' \
FROM PRV_PROD_MAPPING PROD \
WHERE PROD.SERVICE_ID = :service_id \
AND (PROD.KEY || ' ' || PROD.KEY_VAL) \
IN (:keys) "
what :service_id and :keys mean. Could I see the values behind by simple trace.
How could I find where these vars are defined?
Thanks in advance!
It's not TCL its an SQL query embedded in a TCL string, specifically one that binds a variable, which is then assigned to a normal TCL variable
As glenn points out, on its own this snippet of TCL does very little. presuembly somewhere in your program you actually connect to a DB and pass it a query from this string and some other variables
If you're using TDBC, you might have
# assume the connection has already occured and is named "db"
set sql "SELECT ... WHERE a.b=:service_id IN (:keys)"
set statement [db prepare $sql]
# get the bind variables' values from the local context:
set service_id 42
set keys [join {key1 key2 key3} ,]
set resultset [$statement execute]
# or, without setting the "service_id" and "keys" variables,
# provide them as an argument to the execute subcommand
unset service_id keys
set resultset [$statement execute {service_id 24 keys "foo,bar,baz"}]
As others pointed out it you just assign a string* to a variable.
More exactly, you assign the following string to a variable called sql
SELECT PROD.KEY || ' {' || PARAMETERS || '}' FROM PRV_PROD_MAPPING PROD WHERE PROD.SERVICE_ID = :service_id AND (PROD.KEY || ' ' || PROD.KEY_VAL) IN (:keys)
The values of :service_id and :keys are bound values that are passed later (In a oraplexec statement probably).
|| is string concatenation in SQL. So PROD.KEY || ' {' || PARAMETERS || '}' could be PRODKEY {PARAMETERS}.
*Everything is a string
I've done it using traces:
sys.DBMS_SYSTEM.SET_EV(n_sid, n_serial, 10046, 12, '');
DBMS_OUTPUT.put_line('Trace started: ' || to_char(SYSDATE,'dd.mm.yyyy hh24:mi:ss'));

Resources