SQLite does not save string made of zeroes - sqlite

I'm using SQLite 3.7.4 (within my c++ app under Ubuntu PP) and when I try to save string like "000000" it saves just one char "0". I tried it in console too - is it feature, or bug? How can I get rid of that?
For example:
CREATE TABLE status (readTime INTEGER, status STRING);
INSERT INTO status (readTime, status) values(1234, "000000");
INSERT INTO status (readTime, status) values(4321, "111111");
SELECT * FROM status;
1234|0
4321|111111

Some quick research points to the fact that STRING is not a recognized type in SQLite (or, I believe, most other SQL dialects). However, SQLite isn't strict with its types, so the type defaulted to NUMERIC. You should be able to change the column type to TEXT to resolve your issue.
Further reading: Type Affinity

"STRING" isn't a SQLite data type. Try "TEXT".

Related

Delphi - ClientDataSet SQL calculated field causing "Invalid field type" error at runtime [duplicate]

Using Delphi 10.2, SQLite and Teecharts. My SQLite database has two fields, created with:
CREATE TABLE HistoryRuntime ('DayTime' DateTime, Device1 INTEGER DEFAULT (0));
I access the table using a TFDQuery called qryGrpahRuntime with the following SQL:
SELECT DayTime AS TheDate, Sum(Device1) As DeviceTotal
FROM HistoryRuntime
WHERE (DayTime >= "2017-06-01") and (DayTime <= "2017-06-26")
Group by Date(DayTime)
Using the Field Editor in the Delphi IDE, I can add two persistent fields, getting TheDate as a TDateTimeField and DeviceTotal as a TLargeIntField.
I run this query in a program to create a TeeChart, which I created at design time. As long as the query returns some records, all this works. However, if there are no records for the requested dates, I get an EDatabaseError exception with the message:
qryGrpahRuntime: Type mismatch for field 'DeviceTotal', expecting: LargeInt actual: Widestring
I have done plenty of searching for solutions on the web on how to prevent this error on an empty query, but have had not luck with anything I found. From what I can tell, SQLite defaults to the wide string field when no data is returned. I have tried using CAST in the query and it did not seem to make any difference.
If I remove the persistent fields, the query will open without problems on an empty return set. However, in order to use the TeeChart editor in the IDE, it appears I need persistent fields.
Is there a way I can make this work with persistent fields, or am I going to have to throw out the persistent fields and then add the TeeChart Series at runtime?
This behavior is described in Adjusting FireDAC Mapping chapter of the FireDAC's SQLite manual:
For an expression in a SELECT list, SQLite avoids type name
information. When the result set is not empty, FireDAC uses the value
data types from the first record. When empty, FireDAC describes those
columns as dtWideString. To explicitly specify the column data type,
append ::<type name> to the column alias:
SELECT count(*) as "cnt::INT" FROM mytab
So modify your command e.g. this way (I used BIGINT, but you can use any pseudo data type that maps to a 64-bit signed integer data type and is not auto incrementing, which corresponds to your persistent TLargeIntField field):
SELECT
DayTime AS "TheDate",
Sum(Device1) AS "DeviceTotal::BIGINT"
FROM
HistoryRuntime
WHERE
DayTime BETWEEN {d 2017-06-01} AND {d 2017-06-26}
GROUP BY
Date(DayTime)
P.S. I did a small optimization by using BETWEEN operator (which evaluates the column value only once), and used an escape sequence for date constants (which, in real you replace by parameter, I guess; so just for curiosity).
This data type hinting is parsed by the FDSQLiteTypeName2ADDataType procedure that takes and parses column name in format <column name>::<type name> in its AColName parameter.

mysqli_fetch_field_direct wrong result

I was using mysqli_fetch_field_direct on MySQL to get length of fields, using :
$tab_field = mysqli_fetch_field_direct($result_fields,$j);
$long = $tab_field->length;
After creating a varchar(100) under PhpMyAdmin, I got back 100 as my varchar length which was correct.
Now, I'm using MariaDB and the same call to mysqli_fetch_field_direct for the same field, give me 300. I accept the fact that, according to the encoding, maybe it's the "internal size", but I need to know the number of char I can put, so I need to get back "100".
I notice that PhpMyAdmin return 100 when it shows the "structure" of the table, but it seems to use a SHOW query rather than fetch_field_direct.
Any idea?
Let's see SHOW CREATE TABLE. I'll guess that the column is declared CHAR(100)? And the old version was CHARACTER SET latin1? And the MariaDB one was CHARACTER SET utf8?
Generally VARCHAR is preferred over CHAR. (You found one reason.)
Generally utf8 is preferred these days.

SQLite nvarchar(100) field can accept 200 char field. Why?

I have a table with a field defined as nvarchar(100).
I just noticed if inserted a new record (an 200 string value for example) the query works and not throws any exception.
Is a SQLite 'feature'?
Usign SQLite 1.0.94 with Visual Studio 2010 / C# and SQLite v3 dabatabse.
SQLite doesn't recognize the limit you specified in statement, so it's not enforced.
In order to enforce it, you might need a statement like this:
CREATE TABLE t (f TEXT CHECK(LENGTH(f)<101));
So text with more than 100 characters cannot be inserted.
SQLite has a single unlimited TEXT datatype. See the documentation:
http://www.sqlite.org/datatype3.html#affname
Note that numeric arguments in parentheses that following the type
name (ex: "VARCHAR(255)") are ignored by SQLite - SQLite does not
impose any length restrictions on the length of strings, BLOBs or numeric
values.

InvalidCastException for LINQPAD

I'm using LinqPad and IQ driver for SQLite. I have connection with this file. Look:
"Okreslone rzutowanie jest nieprawidlowe" - it can be simple translate to "invalid cast", but Zbiors.Count() return value 8.
When i'm trying do it in SQL query:
select * from zbior
Then all's ok. How can i get same result by "C#", not by SQL query?
Most likely, the types are incorrect. SQLite has a horrible "feature" whereby you can put strings into integer columns and vice versa. The column types are merely suggestion and are not enforced. So what looks like integers in your data might actually be strings, causing in InvalidCastException when the IQ driver tries to read them.

Zumero: Cannot specify column names with a INSERT INTO command

I have started evaluating Zumero with the Zumero Cloud Hosting option.
I have followed the 'Getting Started' guide to the dot.
Once I have created a virtual table, I have tried to insert data via a SQLite Gui Management tool, but the command failed. I have tried 'manually' with 'INSERT INTO' commands but got a error on every field that the Field doesn't exists. It took me quite a while until I figured out that I cannot insert data with the option of specifying Field Names.
So, if I want to insert data, the only option is to do so without specifying field names (and providing values for all fields, of course).
I wonder if this is normal behavior for a Zumero Virtual Table? For any SQLite Virtual table?
I have not taken it to next stage, accessing the table from within a development SDK, but it's hard to believe for me, that inserting any data through the SQLite library will not occur by the library specifying the Field name in his INSERT INTO command implementation.
Any comments is much appreciated.
Thanks.
Looks like you've uncovered a limitation of Zumero's parser. The short answer is, don't use MSSQL-style square brackets to delimit fields when talking to Zumero cloud DBs, instead use standard-SQL-style double quotes.
So:
create virtual table foo using zumero ("Id", "FirstName", "LastName", "Address");
instead of:
create virtual table foo using zumero ([Id], [FirstName], [LastName], [Address]);
Using the first example, you can then insert via:
insert into foo (FirstName, LastName) values ('Fred', 'Flintstone');
or
insert into foo ("FirstName", "LastName") values ('Barney', 'Rubble');
or any combination thereof.

Resources