I have a table with like this:
id
values
user_id
1
["8","7","6"]
5
Now I'm running a query with WHERE condition on values column:
SELECT * from table_name WHERE values = ["8","7","6"]
But MySQL returns this error:
Error Code : 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '["8","7","6"]'
If you want to compare for strict equality, you want to do the comparison as JSON objects. You can do this by using JSON_EXTRACT to parse the data as JSON instead of text:
SELECT * from table_name WHERE
JSON_EXTRACT(`values`, '$') = JSON_EXTRACT('["8","7","6"]', '$');
You should be able to use this for any type of JSON as long as you want strict equality. If you want to return all rows that match the given JSON object, use JSON_CONTAINS.
For example to find all values with the string "8" in it, you'd use the following:
SELECT * from table_name WHERE JSON_CONTAINS(`values`, '"8"');
Note that this matching is not as simple as you'd expect and matches any value in the document. If your data consists of JSON arrays, this should still be adequate.
The information about your column datatype, especially values are crucial. Since the column stores a mix of numbers and non-numbers characters, we can assume that it might be stored in VARCHAR() or TEXT datatype. But since the data format looks like a JSON array, it's also a possibility that the column datatype is JSON. Now both of these datatypes have a very different query structure.
First, let's address some issues:
Whenever the cell values include other characters than numerical, it will be considered as string. Hence, using plain .. WHERE values = ["8","7","6"] without wrapping it in quotes ('), you'll get that Error Code : 1064.
VALUES is a reserved word in MySQL so if you want to stick to it as your table column names, you always need to wrap it in backticks. If not, this will also return Error Code : 1064:
.. WHERE `values` = ..
Now let's try this:
If the column datatype for values is VARCHAR() or TEXT, you just have to simply wrap the search value in single quote like:
SELECT * from table_name WHERE `values` = '["8","7","6"]';
Refer this fiddle
updated for MariaDB
If the column datatype for values is JSON, it's something like this:
SELECT * from table_name where JSON_UNQUOTE(`values`)= '["8","7","6"]'
Refer this fiddle for JSON
The JSON method I've referred to this MariaDB documentation.
P/S: According to this documentation JSON is an alias for LONGTEXT introduced for compatibility reasons with MySQL's JSON data type. In other words, when creating a table with JSON datatype in MariaDB, it will be shown as LONGTEXT but with extra definition than just plain LONGTEXT datatype. See this fiddle for more detail.
Related
After creating an sqlite table with a generated column in it, the type only shows up, if it was specified, and there can be cases when junk gets into the type description as well.
Example:
create table test(
id integer primary key not null,
gen generated always as (id * 2) stored
);
Using pragma table_xinfo(test); afterwards nets the following output:
0|id|INTEGER|1||1|0
1|gen||0||0|3
The type is simply missing from the correct column.
If the column were to be created with:
gen integer generated always as (id * 2) stored
instead, then the type would correctly show up as INTEGER.
Are there any methods that would get the type of a column in a table without having to resort to parsing the table creation code?
Nevermind, as usual, I find the answer right after asking it. According to sqlite documentation:
The datatype and collating sequence of the generated column are determined only by the datatype and COLLATE clause on the column definition. The datatype and collating sequence of the GENERATED ALWAYS AS expression have no affect on the datatype and collating sequence of the column itself.
Which I assume means, that just as in other places, if the datatype is not specified, it is thought of as a blob.
In a React Native App I'm attempting to insert data into a local sqlite db
let submissionID = "1-2-3";
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES("+submissionID+",'Test')");
(dbQuery is the name of a function I made to simplify my queries but the statement inside it should be the same)
If I viewed the Submissions table after this insert statement I would expect to see a row with [ID:"1-2-3",Data:"Test"] but instead I see [ID:"-4",Data:"Test"]
I created the table like so
CREATE TABLE IF NOT EXISTS Submissions(ID BLOB PRIMARY KEY NOT NULL, Data BLOB NOT NULL)
I used Blob because I read "The value is a blob of data, stored exactly as it was input." but I've also tried Text. I've also casted submissionID as a string like so
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES("+String(submissionID)+",'Test')");
But none of that worked. I do see here how sqlite takes advantage of arithmetic operators
https://www.w3resource.com/sqlite/arithmetic-operators.php
but I'm not sure how to stop it from doing so.
How would I get sqlite to treat my hyphens as hyphens instead of subtraction signs?
What you're doing is the equivalent of:
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES(1-2-3,'Test')");
passing the numeric expression 1-2-3 to the INSERT statement. The simplest fix is to quote the string literal.
let submissionID = "1-2-3";
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES('"+submissionID+"','Test')");
However, to guard against SQL injection attacks, you really ought to be using prepared statements instead of using string concatenation to build SQL statements.
Enclose the string in single quotes i.e.
this.dbQuery("INSERT INTO Submissions (ID, Data) VALUES('"+String(submissionID)+"','Test')");
Thus the value is treated as a literal by SQLite, without enclosing the value it will either be treated as a numeric value or as an identifier (column, table, trigger, view depending upon where it is coded and thus what the parser expects).
The data type (column affinity) has little bearing other than if you specified ID INTEGER PRIMARY KEY, then you could not store anything other than an integer. As ID INTEGER PRIMARY key has a special interpretation that is the column is an alias of the rowid.
I used Blob because I read "The value is a blob of data, stored
exactly as it was input." but I've also tried Text. I've also casted
submissionID as a string like so
That is only if the value to be inserted is a BLOB byte[] or in the case of raw SQL x'FF01FE02', otherwise SQLite will store the value according to how it interprets the type should be stored.
I have a table called deliverysimp into which I am trying to insert some data. I am aware that the data types for the columns are just affinities and not restrictions, however I need to store the parcelid column below as TEXT.
CREATE TABLE IF NOT EXISTS deliverysimp (parcelid TEXT, expected integer, primary key (parcelid))
I am using the following javascript to insert the data to the database:
context.executeSql("INSERT INTO deliverysimp(parcelid, expected) values(?,?)",
[
'' + delivery.parcelid,
delivery.expected
], function () { }, me.ErrorHandler);
You can see I have tried to add a blank '' + before the parcelid to try and force the affinity, but the behaviour is the same without; namely:
if I try to store the parcelid 33333333333322222222222222222222223 this is stored into the database as 3.3333333333322223e+34 and I need this to be a text/string representation.
Any ideas how I can get SQLite to honour this as TEXT?
I suspect that you already have a string, just not the string you expected. Since the number you have cannot be represented by an 8-byte integer, it gets converted into a real number and that gets converted into a string, i.e., '3.3333333333322223e+34'. So, if you want the value to be '33333333333322222222222222222222223', then that's what you have to insert into the table.
To check, do a SELECT parcelid, TYPEOF(parcelid) FROM deliverysimp; using the sqlite3 command-line tool and see what you get.
I have a table in which there's a column of type BLOB. Another column is of type 'text'. Something like:
CREATE TABLE Tbl(TXT text, BLB blob);
Now I've inserted a few records using:
INSERT INTO Tbl(TXT) VALUES("whatever");
As you can see nothing was defined for BLB. But each time that I issue a query like:
SELECT * FROM 'Tbl' WHERE 'TXT'="whatever";
I get nothing at all without any error message or anything. My primary guess was that the problem might have something to do with BLB being null or undefined or something like that. Any ideas?
Your query should be:
SELECT * FROM Tbl WHERE TXT="whatever";
You are specifying strings for the table name and for the column. SQL lets you perform queries on values, not just tables.
I'm working on a small SQLite database using the Unix command line sqlite3 command tool. My schema is:
sqlite> .schema
CREATE TABLE status (id text, date integer, status text, mode text);
Now I want to set the column 'mode' to the string "Status" for all entries. However, if I type this:
sqlite> UPDATE status SET mode="Status";
Instead of setting column 'mode' to the string "Status", it sets every entry to the value that is currently in the column 'status'. Instead, if I type the following it does the expected behavior:
sqlite> UPDATE status SET mode='Status';
Is this normal behavior?
This is also a FAQ :-
My WHERE clause expression column1="column1" does not work. It causes every row of the table to be returned, not just the rows where column1 has the value "column1".
Use single-quotes, not double-quotes, around string literals in SQL. This is what the SQL standard requires. Your WHERE clause expression should read: column1='column2'
SQL uses double-quotes around identifiers (column or table names) that contains special characters or which are keywords. So double-quotes are a way of escaping identifier names. Hence, when you say column1="column1" that is equivalent to column1=column1 which is obviously always true.
http://www.sqlite.org/faq.html#q24
Yes, that's normal in SQL.
Single quotes are used for string values; double quotes are used for identifiers (like table or column names).
(See the documentation.)