Issue with replacing NULL sqlite3 database column values with other types in Python 3? - sqlite

I've run into a problem with the sqlite3 module in Python 3, where I can't seem to figure out how to replace NULL values from the database with other ones, mainly strings and integers.
This command doesn't do the job, but also raises no exceptions:
UPDATE table SET animal='cat' WHERE animal=NULL AND id=32
The database table column "animal" is of type TEXT and gets filled with NULLs where no other value has been specified.
The column "id" is primary keyed and thus features only unique integer row indices.
If the column "animal" is defined, not NULL, the above command works flawlessly.
I can replace existing strings, integers, and floats with it.
What am I overlooking here?
Thanks.

The NULL value in SQL is special, and to compare values against it you need to use the IS and IS NOT operators. So your query should be this:
UPDATE table
SET animal = 'cat'
WHERE animal IS NULL AND id = 32;
NULL by definition means "unknown" in SQL, and so comparing a column directly against it with = also produces an unknown result.

Related

Show negative real in SQLite table

I have a column C of type REAL in table F in SQLite. I want to join this everywhere where in another table the negative value of F exists (along with some other fields).
However -C or 0-C etc.. all return the rounded value of C e.g. when C contains "123,456" then -C returns "-123".
Should I cast this via a string first or is the syntax differently?
Looks like the , in 123,456 is meant to be a decimal separator but SQLite treats the whole thing as a string (i.e. '123,456' rather than 123.456). Keep in mind that SQLite's type system is a little different than SQL's as values have types but columns don't:
[...] In SQLite, the datatype of a value is associated with the value itself, not with its container. [...]
So you can quietly put a string (that looks like a real number in some locales) into a real column and nothing bad happens until later.
You could fix the import process to interpret the decimal separator as desired before the data gets into SQLite or you could use replace to fix them up as needed:
sqlite> select -'123,45';
-123
sqlite> select -replace('123,45', ',', '.');
-123.45

Prevent SQLite query from stripping leading zeros from numeric strings?

In my database, a table contains two columns each containing an 8 digit ASCII code, usually it's just alphanumeric. For example, a row might contain A123B45C in col1 and PQ2R4680 in col2.
I need to have a query/view that outputs a 4 character string calculated as the 2nd+3rd chars of these, concatenated. So in this example the extra column value would be 12Q2.
This is a cut-down version of the SQL I'd like to use, although it won't work as written because of zero stripping / conversion:
select
*,
(substr(col1, 2, 2) || substr(col2, 2, 2)) AS mode
from (nested SQL source query)
where (conditions)
This fails because if a row contains A00B23B4 in col1 and P32R4680 in col2, it will evaluate as 0032 and the query output will contain numeric 32 not 0032. (It's worse if col1 contains P1-2345 or "1.23456" or something like that)
Other questions on preventing zero stripping and string to integer conversion in Sqlite, all relate to data in tables where you can define a column text affinity, or static (quotable) data. In this case I can't do these things. I also can only create queries, not tables, so I can't write to a temp table.
What is the best way to ensure I get a 4 character output in all cases?
I believe you issue is not with substr stripping characters as this works as expected e.g. :-
Then running query SELECT substr(col1,2,2) || substr(col2,2,2) as mode FROM stripping
results in (as expected):-
Rather, your issue is likely how you subsequently utilise mode in which case you may need to use a CAST expression CAST expressions
For example the following does what is possibly happening :-
`SELECT substr(col1,2,2) || substr(col2,2,2) as mode, CAST(substr(col1,2,2) || substr(col2,2,2) AS INTEGER) AS oops FROM stripping`
resulting in :-

SQL Server 2012 How to change the data type of a column from bit to datefield?

I have a table Person with a column called onvacation.
This column is of data type bit since it's a boolean in the code. It has values null, 0 and 1.
I would like to change the data type of this column from bit to datetime so that all values that are 1, are converted to a new date (could be current date). and 0 and null values would both be just null.
I tried following w3bschool's tutorial and did a query:
ALTER TABLE Person ALTER COLUMN onvacation datetime
But that gives an error 'DF____Person__onvac__59062A42' is dependent on column 'onvacation'.
you get this error because DF____Person__onvac__59062A42 sql object Depends on onvacation column.
You can Find Dependency of Person table by Right Click-->View Dependancy
remove that dependent object and try to alter column

Query a manual list of data items

I would like to run a query involving joining a table to a manually generated list but am stuck trying to generate the manual list. There is an example of what I am attempting to do below:
SELECT
*
FROM
('29/12/2014', '30/12/2014', '30/12/2014') dates
;
Ideally I would want my output to look like:
29/12/2014
30/12/2014
31/12/2014
What's your Teradata release?
In TD14 there's STRTOK_SPLIT_TO_TABLE:
SELECT *
FROM TABLE (STRTOK_SPLIT_TO_TABLE(1 -- any dummy value
,'29/12/2014,30/12/2014,30/12/2014' -- any delimited string
,',' -- delimiter
)
RETURNS (outkey INTEGER
,tokennum INTEGER
,token VARCHAR(20) CHARACTER SET UNICODE) -- modify to match the actual size
) AS d
You can easily put this in a Derived Table and then join to it.
inkey (here the dummy value 1) is a numeric or string column, usually a key. Can be used for joining back to the original row.
outkey is the same as inkey.
tokennum is the ordinal position of the token in the input string.
token is the extracted substring.
Try this:
select '29/12/2014'
union
select '30/12/2014'
union
...
It should work in Teradata as well as in MySql.

Parametric recursive looped SQLite insert - do all columns have to be supplied?

I added a new column to my table, so there are now 4 instead of 3, and am now getting the following error when do a parametric insert (looped):
table 'test' has 4 columns but 3 values were supplied
Does this mean that you have to code your query for EVERY column the table has (as opposed to just the columns you want populated) when doing inserts, and that SQLite won't just add a default value if a column is missing from the query?
My query is:
"INSERT OR IGNORE INTO test VALUES (NULL, #col2, #col3)"
And this is the code that controls what's inserted in the recursive lopp:
sqlStatement.clearParameters();
var _currentRow:Object = _dataArray.shift();
sqlStatement.parameters["#col2"] = _currentRow.val2;
sqlStatement.parameters["#col3"] = _currentRow.val3;
sqlStatement.execute();
Ideally, I'd like column 4 to be left blank, without having to code it into the query.
Thanks for taking a look.
If you're inserting less values than there are columns, you need to explicitly specify the columns you are inserting to. For example
INSERT INTO test(firstcolumn,secondcolumn) VALUES(1,2);
Those columns that are not specified will get the default value, or NULL if there is no default value.

Resources