SQLite custom functions as match string - sqlite

I create a SQLite function which takes a string and returns another string, then I can use the return value as match strings. Code is here
It works very well except for the single quotes. In this case, it can't match any rows, but if I directly use the returned string, it can match. Anyone know what's the problem here?
sqlite> select simple_query('''');
"''"
sqlite> select ' ', simple_highlight(t1, 0, '[', ']') from t1 where x match simple_query('''');
sqlite> select ' ', simple_highlight(t1, 0, '[', ']') from t1 where x match '"''"';
|#English &special _characters."[']bacon-&and[']-eggs%
Full example here

This question finally answered in sqlite-forum, and I'd like to post the reason in here.
The reason is SQLite will try to escape the string for us, we can verify that after turn on quote mode, as you can see, our return value will be escaped from "'" to "''" by SQLite. Which means we don't need to escape single quote in our function.
sqlite> select simple_query('''');
"'"
sqlite> select simple_query('"');
""""
sqlite> .mode quote
sqlite> select simple_query('"');
'""""'
sqlite> select simple_query('''');
'"''"'

Related

How to *always* display blob value using x'abc' binary string literal syntax?

Very similar to How to display blob value using x'abc' binary string literal syntax?:
How can I have the sqlite3 shell display always display blob columns using the hex notation, as per e.g. quote(blob_column_name), without explicitly using quote, and in select * queries (and other contexts where blob_column_name isn't mentioned explicitly)?
(I suspect the answer is "you can't", but I'm hoping to be pleasantly surprised.)
There are two output modes that use SQL syntax (not only for blobs but for all values):
sqlite> .mode quote
sqlite> SELECT 1, x'123ABC', 'hello', null;
1,X'123abc','hello',NULL
sqlite> .mode insert
sqlite> SELECT 1, x'123ABC', 'hello', null;
INSERT INTO "table" VALUES(1,X'123abc','hello',NULL);

"Row value misused" error in SQLite database

I'm getting an error from an sqlite3 query for which I can't find any reference material. Googling the string takes me deep in the SQLite code itself, and that's so opaque I can't make heads or tails of it.
The table schema:
CREATE TABLE quote (
seqnum INTEGER,
session STRING,
timestamp_sip INTEGER,
timestamp_1 INTEGER,
market_center STRING,
symbol STRING,
bid_price INTEGER,
bid_lots INTEGER,
offer_price INTEGER,
offer_lots INTEGER,
flags INTEGER,
PRIMARY KEY (symbol, seqnum) );
The query:
select (seqnum, session, timestamp_sip, timestamp_1, market_center, symbol)
from quote
where symbol = 'QQQ';
The error:
Error: row value misused
I have no idea how to proceed here. There is plenty of data in the table that would match the query:
sqlite> select count(*) from quote where symbol = 'QQQ';
2675931
Can anyone offer any guidance here? Sqlite version is 3.16.2.
Nevermind. Those parentheses around the select columns (left over from a copy/paste) are the problem. Poor error message, maybe. But my fault.
I had a similar when working with a Rails 5.2 Application.
For my case I was trying to write a search query for a model in application:
def self.search(params)
applications = all.order('created_at DESC') # for not existing params args
applications = applications.where("cast(id as text) like ?, email like ?, first_name like ?, last_name like ?, appref like ?", "#{params[:search]}", "%#{params[:search]}%", "#{params[:search]}", "#{params[:search]}", "#{params[:search]}",) if params[:search]
applications
end
The issue was that I was using a comma (,) to separate the search parameters, I simply corrected by using an OR instead:
def self.search(params)
applications = all.order('created_at DESC') # for not existing params args
applications = applications.where("cast(id as text) like ? OR email like ? OR first_name like ? OR last_name like ? OR appref like ?", "#{params[:search]}", "%#{params[:search]}%", "#{params[:search]}", "#{params[:search]}", "#{params[:search]}",) if params[:search]
applications
end
I deleted brackets from query and it work for me: from SELECT (column1, column2, ...) FROM table to SELECT column1, column2, ... FROM table
JUST
select seqnum, session, timestamp_sip, timestamp_1, market_center, symbol
from quote
where symbol = 'QQQ';
then it works.
Yeah, this bug is happing in my code, and I found this questions, but none of the answers helped me.
I fixed this problem with remove the same column in my SELECT command.
(It's stupid, because I can't select the column if the column is already in the condition subcommand.)
This is the problem SQL command (DO NOT USE THIS):
SELECT (`id`, `username`) FROM `users` WHERE `id` = 'someone_s id'
This is the fixed SQL command (PLEASE USE THIS):
SELECT (`username`) FROM `users` WHERE `id` = 'someone_s id'
The same error occurs when putting the elements of a GROUP BY clause inside brackets, as in
SELECT 1 as a, 2 as b FROM (SELECT 1) GROUP BY (a, b);
The correct syntax is, of course
SELECT 1 as a, 2 as b FROM (SELECT 1) GROUP BY a, b;

How to search my database by using an array of words?

I'm attempting to setup a search function from a string a user types. (ex: "John Doe" or "Doe, John")
I was thinking I would use Replace(SearchString, ",", "") to get rid of the commas the user might enter, and then use Split(SearchString, " ") to get all the words into an array. Once they're in the array I would execute a Stored Procedure on each of the terms and build a DataTable with the results.
Below is what I'm wanting to use for executing my stored procedure.
oCommand = DataAccess.GetSQLCommand("MyStoredProcedure", CommandType.StoredProcedure, SourceServer.ConnectionLocal)
oCommand.Parameters.AddWithValue("#MySearchString", SearchString)
oAdapter = New SqlDataAdapter(oCommand)
oAdapter.Fill(MyDataTable)
Now I'm thinking the "SearchString" I will assign while looping through my array of words... but this doesn't seem like the right way to do this. Maybe it is but I don't know how to append my next result to the previous DataTable either.
There are some great ideas for using arrays and Lists in SQL Server on this page - http://www.sommarskog.se/arrays-in-sql-2005.html
I personally find the XML method the most useful;
http://www.sommarskog.se/arrays-in-sql-2005.html#XML
An example of how I've used this in the past is;
DECLARE #indata nvarchar(max)
DECLARE #hDoc int
SET #indata = '
<ROOT>
<SearchTerm code="Test search term"></SearchTerm>
<SearchTerm code="Other search term"></SearchTerm>
<SearchTerm code="Next search term"></SearchTerm>
</ROOT>'
CREATE TABLE #searchTerm (
code varchar(40)
)
EXEC sp_xml_preparedocument #hDoc OUTPUT, #indata
INSERT Into #searchTerm
SELECT code
FROM OPENXML(#hDoc, '/ROOT/SearchTerm',1)
WITH (code varchar(50))
EXEC sp_xml_removedocument #hDoc
-- Use the data in #searchTerm as needed in your query
SELECT * FROM MyTable WHERE searchValue IN (SELECT code FROM #searchTerm)
DROP TABLE #searchTerm
Try passing in the comma separated values in as a single string of nvarchar. Then use the SELECT FROM WHERE IN structure within your stored procedure. Create the sql command wwithin your stored procedure by concatenation and then call EXEC #sql
Declare #sql =
'SELECT * FROM tbl
WHERE person IN(' + #Application + ')'
exec(#sql)
Beware, if your list of search criteria is large this may not be the best solution for you.
Note that the commas should be between the full names not the first name and last name.

How to insert values into sqlite3 using autohotkey

My problem is I am unable to insert values into sqlite3 using autohot key.
My code is:
MyName := name
myTel := telphonenumber
$sSQL := "insert into myTable Values ('" %MyName% "', " %myTel% ");"
and I also tried with ,
$sSQL := "insert into myTable Values ( ' " . MyName . " ', " . myTel . ");"
But neither of these works.
Any suggestion is appreciated..
I've not used AHK with SQLite before, but is it just the query you're having issues with? Try this (note the lack of the colon before the equals sign):
$sSQL = "insert into myTable Values ('%MyName%', '%myTel%');"
Your second attempt produces a query that is technically valid, but it would put a space either side of the name in the database ('John' would be ' John '). Also I'm guessing you don't really want to be using a numeric field in your database for a telephone number? If a number begins with 0 or is to large you could have issues. The version above will insert it as a string.
MyName := name
myTel := telphonenumber
$sSQL := "insert into myTable Values ('" MyName "', '" myTel "');"
I prefer to put the phone number also into apostrophe.
if you do not have a phone number then there is no error:
insert into myTable Values ('John', '' );
and as Gary said right: "If a number begins with 0 or ... issues."
the select of the telephone number 0177... will give you later 177...
better you also use a string for the phone number and not an number format.
create table myTable
(
name TEXT
phone TEXT
) ;

Escape single quote character for use in an SQLite query

I wrote the database schema (only one table so far), and the INSERT statements for that table in one file. Then I created the database as follows:
$ sqlite3 newdatabase.db
SQLite version 3.4.0
Enter ".help" for instructions
sqlite> .read ./schema.sql
SQL error near line 16: near "s": syntax error
Line 16 of my file looks something like this:
INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there\'s');
The problem is the escape character for a single quote. I also tried double escaping the single quote (using \\\' instead of \'), but that didn't work either. What am I doing wrong?
Try doubling up the single quotes (many databases expect it that way), so it would be :
INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');
Relevant quote from the documentation:
A string constant is formed by enclosing the string in single quotes ('). A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL. BLOB literals are string literals containing hexadecimal data and preceded by a single "x" or "X" character. ... A literal value can also be the token "NULL".
I believe you'd want to escape by doubling the single quote:
INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');
for replace all (') in your string, use
.replace(/\'/g,"''")
example:
sample = "St. Mary's and St. John's";
escapedSample = sample.replace(/\'/g,"''")
Just in case if you have a loop or a json string that need to insert in the database. Try to replace the string with a single quote . here is my solution. example if you have a string that contain's a single quote.
String mystring = "Sample's";
String myfinalstring = mystring.replace("'","''");
String query = "INSERT INTO "+table name+" ("+field1+") values ('"+myfinalstring+"')";
this works for me in c# and java
In C# you can use the following to replace the single quote with a double quote:
string sample = "St. Mary's";
string escapedSample = sample.Replace("'", "''");
And the output will be:
"St. Mary''s"
And, if you are working with Sqlite directly; you can work with object instead of string and catch special things like DBNull:
private static string MySqlEscape(Object usString)
{
if (usString is DBNull)
{
return "";
}
string sample = Convert.ToString(usString);
return sample.Replace("'", "''");
}
In bash scripts, I found that escaping double quotes around the value was necessary for values that could be null or contained characters that require escaping (like hyphens).
In this example, columnA's value could be null or contain hyphens.:
sqlite3 $db_name "insert into foo values (\"$columnA\", $columnB)";
Demonstration of single quoted string behavior where complexity or double quotes are not desired.
Test:
SELECT replace('SAMY''S','''''','''');
Output:
SAMY'S
SQLite version:
SELECT sqlite_version();
Output:
3.36.0

Resources