Converting to Datum type in PostgreSQL - c

I see that the fetchfunc is used to access the column values of the sample rows fetched for statistics collection. The function returns a Datum. Individually when we know of the datatype, we can use the functions like Float8GetDatum Int16GetDatum and so on to convert to Datum type.
My problem is:
Input : a column in a relation and a valid value that the column can take.
I have to find the datatype of the column and based on that, I need to use the right function to convert the given input value to the Datum value to be stored internally.
I am very confused on how to go about this in postgreSQL.

Related

ORA-22835: Buffer too small and ORA-25137: Data value out of range

We are using a software that has limited Oracle capabilities. I need to filter through a CLOB field by making sure it has a specific value. Normally, outside of this software I would do something like:
DBMS_LOB.SUBSTR(t.new_value) = 'Y'
However, this isn't supported so I'm attempting to use CAST instead. I've tried many different attempts but so far these are what I found:
The software has a built-in query checker/validator and these are the ones it shows as invalid:
DBMS_LOB.SUBSTR(t.new_value)
CAST(t.new_value AS VARCHAR2(10))
CAST(t.new_value AS NVARCHAR2(10))
However, the validator does accept these:
CAST(t.new_value AS VARCHAR(10))
CAST(t.new_value AS NVARCHAR(10))
CAST(t.new_value AS CHAR(10))
Unfortunately, even though the validator lets these ones go through, when running the query to fetch data, I get ORA-22835: Buffer too small when using VARCHAR or NVARCHAR. And I get ORA-25137: Data value out of range when using CHAR.
Are there other ways I could try to check that my CLOB field has a specific value when filtering the data? If not, how do I fix my current issues?
The error you're getting indicates that Oracle is trying to apply the CAST(t.new_value AS VARCHAR(10)) to a row where new_value has more than 10 characters. That makes sense given your description that new_value is a generic audit field that has values from a large number of different tables with a variety of data lengths. Given that, you'd need to structure the query in a way that forces the optimizer to reduce the set of rows you're applying the cast to down to just those where new_value has just a single character before applying the cast.
Not knowing what sort of scope the software you're using provides for structuring your code, I'm not sure what options you have there. Be aware that depending on how robust you need this, the optimizer has quite a bit of flexibility to choose to apply predicates and functions on the projection in an arbitrary order. So even if you find an approach that works once, it may stop working in the future when statistics change or the database is upgraded and Oracle decides to choose a different plan.
Using this as sample data
create table tab1(col clob);
insert into tab1(col) values (rpad('x',3000,'y'));
You need to use dbms_lob.substr(col,1) to get the first character (from the default offset= 1)
select dbms_lob.substr(col,1) from tab1;
DBMS_LOB.SUBSTR(COL,1)
----------------------
x
Note that the default amount (= length) of the substring is 32767 so using only DBMS_LOB.SUBSTR(COL) will return more than you expects.
CAST for CLOB does not cut the string to the casted length, but (as you observes) returns the exception ORA-25137: Data value out of range if the original string is longert that the casted length.
As documented for the CAST statement
CAST does not directly support any of the LOB data types. When you use CAST to convert a CLOB value into a character data type or a BLOB value into the RAW data type, the database implicitly converts the LOB value to character or raw data and then explicitly casts the resulting value into the target data type. If the resulting value is larger than the target type, then the database returns an error.

Can I get plain value of columns with DbDataReader

I need to get the value in numeric columns from the DB exactly it is formatted. When I get it with the DBDataReader for the numeric columns it automatically converts them to Int32 or Decimal and I get unwanted zeroes after the decimal point.
So is there a way I can get just the plain value (string) from a column like this? Due to nature of the page I don't want to format them in the code I just want the plain value from the DB.
I tried to get it with GetValue method of DBDataReader but the method is working only for nvarchar columns.
Update from comments:
I am dealing with unknown columns and types (user select SQL View out of many) and I dynamically create everything. But I don't know the types of the columns nor their preferred formatting. So this is the reason I want the value as it is recorded in the DB. Do you think I can get it as a string?
Like Larnu said in the comments this is accurate mappings for numeric columns for int32 and int. That being said depending on what youre actually trying to do with this data, you could try either using this:
reader[index].ToString();
or you could try doing
reader.GetInt32(index)

Find rows with exact geography coordinates

I have a SQL table with a geography column. When I look at one of the rows the geography shows as a long hex string: 0xE6100....C0.
I want to write a query that finds all other rows in my database that have this same value. How can I do this?
I tried adding WHERE location = '0xE6100....C0' with and without quotes but I get an error:
Invalid operator for data type. Operator equals equal to, type equals geography.
Note: I'm just doing this query in an ad-hoc fashion I'm not really looking for a optimal solution or a way to parameterize this in any way. I just have a row that I'd like to find related values.
Looks like you need to use .STEquals
Check the documentation here

Format numbers in data field of SSRS Matrix with two different number types using an expression

So, I have an SSRS report with a matrix. The columns, rows and data field are fed by expressions that refer to parameters. Effectively giving the report a pivot table style effect.
The data field has two values in the #prmDataField parameter to pick from when running the report. One is called LengthOfStayand in the databse is all integers. The second is called FinalCostand in the real world would be currency (GBP in this case) but of course in the database it's just a float.
There's a 4th parameter to apply an aggregate function to the data in the data field that's as follows;
=SWITCH
(
Parameters!prmFunction.Value="Avg",AVG(Fields(Parameters!prmDataField.Value).Value)
,Parameters!prmFunction.Value="Sum",SUM(Fields(Parameters!prmDataField.Value).Value)
,Parameters!prmFunction.Value="Max",MAX(Fields(Parameters!prmDataField.Value).Value)
,Parameters!prmFunction.Value="Min",MIN(Fields(Parameters!prmDataField.Value).Value)
)
My problem: I'm hoping there's a way to enter an expression into the Number format property of the data field textbox of the matrix so the data on the report will format depending on which of the datafield parameter values have been selected to run the report with. So if you pick LengthOfStaythe report will display the numbers as appropriately formatted integers. If you pick FinalCostthe report will display the numbers as currency instead.
I attempted this;
=SWITCH
(Parameters!prmDataField.Value=Fields!Length_of_Stay.Value,"G-int32"
,Parameters!prmDataField.Value=Fields!Spell_Final_Cost.Value,"C")
But it didn't work and I got the following warning back once the report had run;
Warning 1 [rsRuntimeErrorInExpression] The Format expression for the textrun ‘Textbox17.Paragraphs[0].TextRuns[0]’ contains an error: Input string was not in a correct format.'
Is it even possible to have two different number types for formatting depending on a parameter value or any other value?

Error in storing values in SQL database table

In my table, there is a column called zipcode whose datatype is int. And when I am storing a zipcode which starts with 0 (for eg. 08872), it is getting stored as 8872.
Can anybody explain me why is it happening?
An INT value is numeric - and numerically, 08872 and 8872 are identical - both represent the value 8872.
SQL Server will not store leading zeroes for numerical values. That's just the way it is.
Either store this as CHAR(5) instead, or handle the formatting (adding leading zeroes to your zip codes) on the frontend when you need to display it.

Resources