How to assign null to a nullable byte in c# - exception

advert.AC = String.IsNullOrEmpty(reader["AC"].ToString()) ? null : Byte.Parse(reader["AC"].ToString());
I want to assign null to the property named AC when there is null record in reader["AC"] otherwise assign the value to AC by parsing it into Byte. The type of AC is "Byte?" in my case but it is giving an error in the above assignment.
Type of conditional expression cannot be determined because there is no implicit conversion between '' and 'byte' C:\Users\Waheed Ahmed\documents\visual studio 2010\Projects\Autos\Autos\Controllers\autosController.cs 274 85 Autos

You can refer here Conditional operator assignment with Nullable<value> types?
If you do need to cast the null to Byte? and then use it , like
advert.AC = String.IsNullOrEmpty(reader["AC"].ToString()) ? (Byte?)null : Byte.Parse(reader["AC"].ToString());

Related

MySql doesn't accept boolean as its column datatype

I have a Java program which stores data in MySQL database in two states. For this purpose I wanted to use BOOLEAN. But whenever I enter BOOLEAN it's getting changed into TINYINT.
Is there any other way to store data in two states?
MySQL uses TINYINT(1) to mimic the behaviour of Boolean type, so make sure you use TINYINT(1) as the data type of your column, not TINYINT.
Alternatively, you can use BOOL or BOOLEAN which are both synonyms for TINYINT(1).
Similarly, the values TRUE and FALSE are merely aliases for 1 and 0, respectively in MySQL.
MySQL doesn't have a native boolean type.
https://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html says:
BOOL, BOOLEAN
These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true:
This means the "boolean" type is still an 8-bit signed integer, and the (1) syntax is not a size limit. It doesn't prevent the column from storing integer values from -128 to 127. It's up to you to refrain from storing those values.
MySQL also supports a BIT data type: https://dev.mysql.com/doc/refman/5.7/en/bit-type.html
The MySQL JDBC driver translates BIT(1) into java.lang.Boolean. See https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-type-conversions.html for JDBC data type mappings.
But the BIT data type has had some bugs in its history. I avoid using it.
Bit probably won't save any space, anyway, if that's what you are hoping for. If you had a bunch of BIT columns defined consecutively in your table, they would be stored compactly, up to 8 columns per byte. But the minimum storage is still 1 byte, so if you had 1 BIT column, it would still take a whole byte.
Re your questions:
It doesn't take much code to test this out.
I created a test table and put one row of values in it:
CREATE TABLE `foo` (
`b` bool DEFAULT '1', /* this is a synonym for TINYINT(1) */
`ti` tinyint DEFAULT '1',
`tiu` tinyint unsigned DEFAULT '1',
`si` smallintDEFAULT '1',
`siu` smallint unsigned DEFAULT '1',
`i` int DEFAULT '1',
`iu` int unsigned DEFAULT '1',
`bi` bigint DEFAULT '1',
`biu` bigint unsigned DEFAULT '1'
);
INSERT INTO foo () VALUES ();
Then I called some JDBC code and used getObject() for each column, and asked it to tell me what data type it returned:
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM foo");
while (rs.next()) {
Object b = rs.getObject("b");
System.out.println("b ("+b.getClass().getSimpleName()+"):\t" + b);
Object ti = rs.getObject("ti");
System.out.println("ti ("+ti.getClass().getSimpleName()+"):\t" + ti);
Object tiu = rs.getObject("tiu");
System.out.println("tiu ("+tiu.getClass().getSimpleName()+"):\t" + tiu);
Object si = rs.getObject("si");
System.out.println("si ("+si.getClass().getSimpleName()+"):\t" + si);
Object siu = rs.getObject("siu");
System.out.println("siu ("+siu.getClass().getSimpleName()+"):\t" + siu);
Object i = rs.getObject("i");
System.out.println("i ("+i.getClass().getSimpleName()+"):\t" + i);
Object iu = rs.getObject("iu");
System.out.println("iu ("+iu.getClass().getSimpleName()+"):\t" + iu);
Object bi = rs.getObject("bi");
System.out.println("bi ("+bi.getClass().getSimpleName()+"):\t" + bi);
Object biu = rs.getObject("biu");
System.out.println("biu ("+biu.getClass().getSimpleName()+"):\t" + biu);
}
Output:
b (Boolean): true
ti (Integer): 1
ti2 (Integer): 1
tiu (Integer): 1
si (Integer): 1
siu (Integer): 1
i (Integer): 1
iu (Long): 1
bi (Long): 1
biu (BigInteger): 1
I'm testing with MySQL Connector/J 5.1.44.
So it seems that TINYINT(1) is handled specially by the JDBC driver. It automatically converts it to a java.lang.Boolean.
Again, TINYINT(1) has no real effect on the range of possible values in MySQL. It's an 8-bit signed integer type. But the JDBC driver has special code to look for the (1) length option and it uses that as an advisory to make it cast to a java.lang.Boolean.
java.lang.Integer is okay up to the unsigned 32-bit INT, then it has to use java.lang.Long to handle the unsigned INT. Then a BigInteger for an unsigned BIGINT. Java integer types are not unsigned, so to handle the larger values of an unsigned INT or BIGINT, Java has to use the larger Integer type.
Boolean and TINYINT(1) are synonyms in mysql, meaning that you can use them interchangeably without raising any problem.

CActiveRecord Find By Attributes Where Field Is Null

In Yii 1.1.*, how to find all data (via CActiveRecord implementation) where an attributes is NULL, kinda like:
Foo::model()->findAllByAttributes(['bar' => 'baz', 'qux' => [null, '']]);
It DOES NOT work because it produces query: WHERE (bar = 'baz') AND (qux IN (, ''))
I want to find all Foo records where:
"bar" field equals with "baz"
AND qux field IS NULL or equals with empty string
I can do it with findAll, but how about if I want to use findAllByAttributes method? Thanks.
Something like:
$cityModel = Cities::model()->findAllByAttributes(array("citny_name"=>"d"), "state_id IS NULL OR state_id = ''");
The executed query:
SELECT * FROM `cities` `t` WHERE `t`.`citny_name`=:yp0 AND
(state_id IS NULL OR state_id = ''). Bound with :yp0='d'
You can pass the condition for quz as an additional parameter into findAllByAttributes:
Foo::model()->findAllByAttributes(['bar' => 'baz'], "quz IS NULL OR quz = ''")
You can't use IN with null values unless you replace CDbCommandBuilder with your own implementation. CActiveRecord::findAllByAttributes calls CDbCommandBuilder::createColumnCriteria which in turn calls CDbCommandBuilder::createInCondition if the column values are an array.
From the source code values are cast into the column type and quoted afterwards and passed through implode resulting in the null being treated as php's null not mysql's null:
foreach($values as &$value)
{
$value=$column->typecast($value);
if(is_string($value))
$value=$db->quoteValue($value);
}
...
return $prefix.$column->rawName.' IN ('.implode(', ',$values).')';

Postgres JSON equivalent to HSTORE subtract operator

Postgres' hstore extension has a neat subtraction operator:
hstore - text[]
hstore - hstore
In the first case, it removes the key/value pairs where the keys are found in the array of strings: in the second case it removes all matching key/value pairs from the first hstore that appear in the second hstore.
It seems this operator does not exist for the new jsonb data type. Is there a simple way to perform these tasks?
The key is the json_each() function, and the ability in PostgreSQL to manually build up a json value.
Here is a function which can handle json - text[]:
CREATE OR REPLACE FUNCTION "json_object_delete_keys"(
"json" json,
VARIADIC "keys_to_delete" TEXT[]
)
RETURNS json
LANGUAGE sql
IMMUTABLE
STRICT
AS $function$
SELECT COALESCE(
(SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}')
FROM json_each("json")
WHERE "key" <> ALL ("keys_to_delete")),
'{}'
)::json
$function$;
To handle the json - json case, you simple need to change the WHERE clause:
WHERE "json"->>"key" <> ("remove"->>"key")),
Accepted answer is great, but would be improved for the json - json case by checking for null as well:
WHERE NOT null_as_value_cmp((this_j->>"key"), (that_j->>"key"))
Without the NULL check you get {} instead of {"a":1}:
# select json_subtract('{"a":1, "b":2}'::json, '{"b":2}'::json);
json_subtract
---------------
{}
(1 row)
null_as_value_cmp is something like this and gets around JsNull being represented as the database NULL
CREATE OR REPLACE FUNCTION null_as_value_cmp(
a text,
b text
)
RETURNS boolean
LANGUAGE sql
IMMUTABLE
CALLED ON NULL INPUT
AS $function$
SELECT CASE
WHEN a IS NULL AND b IS NULL THEN
TRUE
WHEN (a IS NULL AND b IS NOT NULL) THEN
FALSE
WHEN (a IS NOT NULL AND b IS NULL) THEN
FALSE
WHEN a = b THEN
TRUE
ELSE
FALSE
END;
$function$;
[I don't have enough reputation to comment; not sure on the SO protocol here.]

How to use null||d.AM_Answer for select query

I'm getting data from database and using union for joining 2 table. But I need to use null || d.AM_Answer. Here I'm using only null, null. But it's taking only null value coming. If I stored the answer, I'm not getting answer. So, I need to use null || d.AM_Answer.
select
b.QM_ID, b.QM_QCM_ID, b.QM_Question, b.QM_Type, b.QM_Parent_Id, null, null
from
question_master b
INNER JOIN Assessment_master d
on ( d. AM_QM_ID = b.QM_Parent_Id
AND d.AM_HNM_ID = %d
AND d.AM_HM_ID = %d
and d.AM_ASM_Local_Id = %# )
You can use ifnull to check if a field is null or not. If not null, then use field value.
Example:
IFNULL( d.AM_Answer, null )
This returns value of d.AM_Answer if it is not null.
And, you have some errors in your value comparison statements.
AND d.AM_HNM_ID = %d
AND d.AM_HM_ID = %d
AND d.AM_ASM_Local_Id = %#
If %d and %# are place holders for numerics, then it is wrong way of input.
For runtime value inputs, you have to use ? place holder and use prepared statements to bind values on those parameters.
AND d.AM_HNM_ID = ?
AND d.AM_HM_ID = ?
AND d.AM_ASM_Local_Id = ?
Use your server side scripting language for value binding.
Refer to:
MySQL: IFNULL(expr1,expr2)

MYSQL Using UPDATE, WHEN THEN with a NULL value

I'm trying to figure out why I'm not getting a result from a MySQL Query I'm running.
I'm trying to replace a NULL value with a number with in a query, but I can't figure out what I'm doing wrong.
Here's my query:
UPDATE Details
SET HowHear_ID = CASE HowHear_ID
WHEN '' THEN 25
WHEN NULL THEN 25
WHEN 7 THEN 25
WHEN 8 THEN 5
WHEN 16 THEN 25
WHEN 17 THEN 16
END
WHERE HowHear_ID IN ('',NULL,7,8,16,17)
This Query will effect all but the NULL values.
What am I doing wrong??
No value will ever equal (or "unequal") NULL in SQL. Understand the following truth table:
NULL = NULL yields NULL -- not FALSE!
NULL != NULL yields NULL -- not TRUE!
[ANY] = NULL yields NULL -- not FALSE!
[ANY] != NULL yields NULL -- not TRUE!
Since the following are equivalent...
[expression] IN (a, b, c)
[expression] = ANY (a, b, c)
[expression] = a OR [expression] = b OR [expression] = c
... you cannot put NULL on the right hand side of an IN predicate. Interestingly, things get even worse when you put NULL on the right hand side of a NOT IN predicate:
[expression] NOT IN (a, b, c)
[expression] != ANY (a, b, c)
[expression] != a AND [expression] != b AND [expression] != c
If b were NULL, the whole expression will become NULL (or maybe FALSE), but never TRUE. This is also the case for NOT IN (subselect) predicates! So, never do this:
[expression] NOT IN (NULL, 1, 2)
The correct solution in your case uses a NULL predicate instead. Do this:
UPDATE Details
SET HowHear_ID = CASE
WHEN HowHear_ID = '' THEN 25
WHEN HowHear_ID IS NULL THEN 25 -- Use a NULL predicate here
WHEN HowHear_ID = 7 THEN 25
WHEN HowHear_ID = 8 THEN 5
WHEN HowHear_ID = 16 THEN 25
WHEN HowHear_ID = 17 THEN 16
END
WHERE HowHear_ID IN ('',7,8,16,17)
OR HowHear_ID IS NULL -- Use a NULL predicate here
Or this:
WHERE COALESCE(HowHear_ID, '') IN ('',7,8,16,17)
You can't reference NULL in a WHERE clause and get the results you expect. NULL behaves differently to other values.
If you need to reference it, you need to use the isnull() function.
in your case, you would write something like this:
WHERE HowHear_ID IN ('',7,8,16,17) or isnull(HowHear_ID)
By the way, you haven't specified the data type of the field. I assume it's an integer though. In that case, it might be better to check for zero rather than an empty string? (if it isn't an integer, then perhaps it should be)
You can achieve that with
WHERE HowHear_ID IN ('',7,8,16,17) OR HowHear_ID IS NULL