The problem is that I need to compare two fields of different types in a SOQL query.
TextField is a Picklist (so really text) and IntField is a Number(2, 0). Changing the types of these fields is not possible.
I would like to write SOQL like;
SELECT Id FROM SomeObject__c
WHERE Cast(TextField as Integer) > IntField
Obviously Cast(TextField as Integer) does NOT work.
Any advise on type conversion within SOQL. The normal APEX functions (e.g. integer.valueof) don't seem to be of any help here.
Thanks
SOQL itself does not support casting but you can always lend a helping hand ;)
Create a Numeric formula field in SomeObject__c:
IF(ISNUMBER(TextField__c), VALUE(TextField__c), NULL)
or something similar depending on your definition of cast to int. Now you can use this field in a SOQL query.
Related
I'm building a framework for rust-postgres.
I need to know what value type will be returned from a row.try_get, to get the value in a variable of the appropriate type.
I can get the sql type from row.columns()[index].type, but not if the value is nullable , so i can't decide to put the value in a normal type or a Option<T>.
I can use just the content of the row to understand it, i can't do things like "get the table structure from Postgresql".
is there a way?
The reason that the Column type does not expose any way to find out if a result column is nullable is because the database does not return this information.
Remember that result columns are derived from running a query, and that query may contain arbitrary expressions. If the query was a simple SELECT of columns from a table, then it would be reasonably simple to determine if a column could be nullable.
But it could also be a very complex expression, derived from multiple columns, subselects or even custom functions. Postgres can figure out the data type of each column, but in the general case it doesn't know if a result column may contain nulls.
If your application is only performing simple queries, and you know which table column each result column comes from, then you can find out if that table column is nullable like this:
SELECT is_nullable
FROM information_schema.columns
WHERE table_schema='myschema'
AND table_name='mytable'
AND column_name='mycolumn';
If your queries are not that simple then I recommend you always get the result as an Option<T> and handle the possibility that the result might be None.
I am trying to understand the implicit cast behavior.
I have a column called ticketNo, this is a string and it is a pk.
Using the same datatype in both sides, I am returning one row
SELECT * FROM demo d WHERE ticketNo = "1762386738153"
When I am doing a explicit cast, this query is returning the same row
SELECT * FROM demo d WHERE cast (ticketNo as Long)= 1762386738153
Now, when I am doing an implicit cast, this query is returning no rows
SELECT * FROM demo d WHERE ticketNo = 1762386738153
Any ideas ?
There is no implicit cast behavior in Oracle NoSQL Database. String types are not comparable to Long types so the predicate ticketNo = 1762386738153 returns always false in your case. A string item is comparable to another string item. A string item is also comparable to an enum item.
In your case, this is your primary key, in order to have the best performances, it is not recommended to do a CAST. Validate the types before do this query. A primary key is always typed, no wildcard or complex types are accepted
Otherwise,
the reason for returning false for incomparable items, instead of
raising an error, is to handle truly schemaless applications, where
different table rows may contain very different data or differently
shaped data. As a result, even the writer of the query may not know
what kind of items an operand may return and an operand may indeed
return different kinds of items from different rows.
you can always execute the explicit CAST operation when needed, as you did.
If you are interested in have more information : https://docs.oracle.com/en/database/other-databases/nosql-database/20.3/sqlreferencefornosql/value-comparison-operators.html
I store the following rows in my table ('DataScreen') under a JSONB column ('Results')
{"Id":11,"Product":"Google Chrome","Handle":3091,"Description":"Google Chrome"}
{"Id":111,"Product":"Microsoft Sql","Handle":3092,"Description":"Microsoft Sql"}
{"Id":22,"Product":"Microsoft OneNote","Handle":3093,"Description":"Microsoft OneNote"}
{"Id":222,"Product":"Microsoft OneDrive","Handle":3094,"Description":"Microsoft OneDrive"}
Here, In this JSON objects "Id" amd "Handle" are integer properties and other being string properties.
When I query my table like below
Select Results->>'Id' From DataScreen
order by Results->>'Id' ASC
I get the improper results because PostgreSql treats everything as a text column and hence does the ordering according to the text, and not as integer.
Hence it gives the result as
11,111,22,222
instead of
11,22,111,222.
I don't want to use explicit casting to retrieve like below
Select Results->>'Id' From DataScreen order by CAST(Results->>'Id' AS INT) ASC
because I will not be sure of the datatype of the column due to the fact that JSON structure will be dynamic and the keys and values may change next time. and Hence could happen the same with another JSON that has Integer and string keys.
I want something so that Integers in Json structure of JSONB column are treated as integers only and not as texts (string).
How do I write my query so that Id And Handle are retrieved as Integer Values and not as strings , without explicit casting?
I think your assumtions about the id field don't make sense. You said,
(a) Either id contains integers only or
(b) it contains strings and integers.
I'd say,
If (a) then numerical ordering is correct.
If (b) then lexical ordering is correct.
But if (a) for some time and then (b) then the correct order changes, too. And that doesn't make sense. Imagine:
For the current database you expect the order 11,22,111,222. Then you add a row
{"Id":"aa","Product":"Microsoft OneDrive","Handle":3095,"Description":"Microsoft OneDrive"}
and suddenly the correct order of the other rows changes to 11,111,22,222,aa. That sudden change is what bothers me.
So I would either expect a lexical ordering ab intio, or restrict my id field to integers and use explicit casting.
Every other option I can think of is just not practical. You could, for example, create a custom < and > implementation for your id field which results in 11,111,22,222,aa. ("Order all integers by numerical value and all strings by lexical order and put all integers before the strings").
But that is a lot of work (it involves a custom data type, a custom cast function and a custom operator function) and yields some counterintuitive results, e.g. 11,111,22,222,0a,1a,2a,aa (note the position of 0a and so on. They come after 222).
Hope, that helps ;)
If Id always integer you can cast it in select part and just use ORDER BY 1:
select (Results->>'Id')::int From DataScreen order by 1 ASC
I have created a data type called id which consists of two text values:
id(text, text)
I now need to cast values to this data type before they are inserted into my table. How would I go about doing this?
I created the type as follows:
CREATE TYPE ID AS(id text, source text);
Well, to create a cast you need a function that takes a value of one type as your input and outputs the type you wish to cast to (in this case "ID" - which I would name a little more verbose if I were you). What type do you want to cast from?
Realize without messing with all that, you should be able to use your type according to this page.
Just..
SELECT ROW('foo','bar')::ID ;
You have to tell PostgreSQL how to cast, CREATE CAST
if we are talking about "user defined types" which are realy compatible with each other, so you can cast the type to text first and then to your custom type admin_action::text::"UserAction"
in my case "admin_action" was of type "AdminAction" and couldn't be converted to "UserAction" directly, but I've done it through "text" step.
I have a bunch of dimension tables that have unique ID and Name fields. I need a T-SQL function that returns an ID when passed a table name and a value for the name field.
I'm guessing the function would build a little query then execute it? Performance isn't an issue since this is a one time ETL thing.
Sounds like you want a scalar user defined function
There's a lot of other ways to do it though, and udf's certainly can have some perfomance issues.