SSIS Conditional Split Error - The data type DT_BYTES cannot be used with binary operator "==" - sql-server

While configuring a conditional split component with the following expression:
[VersionStamp_Source] == (DT_I8)[VersionStamp_Destination]
I am getting the following error:
The data type DT_BYTES cannot be used with binary operator "==".
Screenshot:

As shown in the error message, one of the columns used in the conditional split expression has a data type of DT_BYTES which cannot be compared using binary operators.
You need to cast this column to another data type. As mentioned in the official documentation, DT_BYTES can be converted to DT_I8 or to a string data type.
As #billinkc mentioned in the comments, casting DT_BYTES to a string data type is more preferable since some values cannot be converted to an 8-byte integer.
To solve your problem, try using the following expression:
(DT_WSTR,255)[VersionStamp_Source] == (DT_WSTR,255)[VersionStamp_Destination]
Also, make sure to use an accurate length for the string casting operator. You can increase the string length to 4000

Related

ADF Data Flow: how to converting hex string to integer

I am trying to convert 32 character hex string generated using md5 to an integer to get mod 10000. Can someone help me with this?
The steps I followed are as below:
Using derived column in Azure data factory Dataflow and inside expression builder, I am adding the below text:
md5(id) where id can be any constant for example.
The above command provides 32 character Hex string. Now I would like to convert it to an integer and then take mod(%) of 100000.

PostgreSQL convert anyarray to array of type int

I am trying to work with the pg_stats relation to learn more about how PostgreSQL does query evaluation.
I am trying to follow this page here: https://www.postgresql.org/docs/10/row-estimation-examples.html to calculate some of the selectivity on my queries.
When working with the histogram_bounds as obtained from
SELECT histogram_bounds
FROM pg_stats
WHERE tablename='<table_name>'
AND attname='<att_name>';
where att_name here is an attribute of numerical type in the table table_name
The returned value is of type anyarray, even though (in my case) the attribute is an integer, so it's an anyarray full of integers. I have found very little documentation on this type, but it seems I can't use the simple cast conventions for getting it to a usable type. Apparently it does not support normal array options. I would like to cast this to an array of ints.
histogram_bounds[0]
ERROR: cannot subscript type anyarray because it is not an array
And cannot be cast
CAST(histogram_bounds as int[])
ERROR: cannot cast type anyarray to integer[]
Any help with how to cast this type to an int array would be very much appreciated.
I think you can cast any type, even the anyarray one, to text for output. This text will have the integer array representation for a histogram of an integer column, so we can subsequently cast it to that:
SELECT histogram_bounds::text::int[]
FROM pg_stats
WHERE tablename='<table_name>'
AND attname='<att_name>';

which is the fastest date compare way

There is a column which is date type, but the parameter passed in the procedure is a string, so can I convert this column to string or convert the passed parameter to date then compare them?
Converting the parameter to date is faster
Date is an integer data type with a fixed length. Thus the comparison is faster except for very short strings.
Converting always takes time. Converting a value once is faster than converting a value n-times.
Additionally: Converting to string and comparing outright only lets you compare for equality or inequality. Not lesser than or greater than etc.
Pretty simple to reason this one out:
If you keep it a string SQL will, for each row, have to convert the date(time) column's value to a string and then compare. On a table with millions of rows that will be an expensive operation since it needs to do this for every row.
If you convert the string parameter to a datetime SQL can do direct comparisons with the converted value on each row.
Besides the above which could've been reasoned quite simply when just stopping and thinking about it there are a lot of pitfalls like Larnu1 pointed out; only equality will work (best-case), greater-than, less-than, between and such won't work as expected.
Also, a date(time) comparison will be a lot quicker since it's a single 8-byte* value that can be compared with a single instruction (or very few) on the CPU instead of having to iterate all chars in the string for comparison.
Look up Sargeability; another argument to convert to datetime.
Best is to get rid of the string alltogether and expect a datetime passed. This makes your interface convey what you need much more clearly (and also rules out problems with date/time conversions like 6/2/2020, is it Jun 2nd or Feb 6th or ...?).
* Depending on the exact datetime type you're using this may differ.

Postgres C Function - Passing & Returning Numerics

I am just beginning to test with Postgres External C Functions. When I pass in a Numeric and Return it the function works fine. (Example)
Sample Function
PG_FUNCTION_INFO_V1(numericTesting);
Datum
numericTesting(PG_FUNCTION_ARGS)
{
Numeric p = PG_GETARG_NUMERIC(0);
PG_RETURN_NUMERIC(p);
}
However, when I try to do any math functions on the variable passed in, it will not compile. I get
error: invalid operands to binary *
Sample Function
PG_FUNCTION_INFO_V1(numericTesting);
Datum
numericTesting(PG_FUNCTION_ARGS)
{
Numeric p = PG_GETARG_NUMERIC(0);
PG_RETURN_NUMERIC(p * .5);
}
What is causing this? I'm guessing the the Numeric datatype needs some function to allow math. I tried using: PG_RETURN_NUMERIC(DatumGetNumeric(p * .5)) but that had the same result.
Numeric isn't a primitive type so you can't do arithmetic operations on it directly. C doesn't have operator overloading, so there's no way to add a multiply operator for Numeric. You'll have to use appropriate function calls to multiply numerics.
As with most things when writing Pg extension functions it can be helpful to read the source and see how it's done elsewhere.
In this case look at src/backend/utils/adt/numeric.c. Examine Datum numeric_mul(PG_FUNCTION_ARGS) where you'll see it use mul_var(...) to do the work.
Unfortunately mul_var is static so it can't be used outside numeric.c. Irritating and surprising. There must be a reasonable way to handle NUMERIC from C extension functions without using the spi/fmgr to do the work via SQL operator calls, as you've shown in your comment where you use DirectFunctionCall2 to invoke the numeric_mul operator.
It looks like the public stuff for Numeric that's callable directly from C is in src/include/utils/numeric.h so let's look there. Whoops, not much, just some macros for converting between Numeric and Datum and some helper GETARG and RETURN macros. Looks like usage via the SQL calls might be the only way.
If you do find yourself stuck using DirectFunctionCall2 via the SQL interfaces for Numeric, you can create a Numeric argument for the other side from a C integer using int4_numeric.
If you can't find a solution, post on the pgsql-general mailing list, you'll get more people experienced with C extensions and the source code there. Link back to this post if you do so.
A way to sidestep this problem altogether is to use data type coercion. Declare your SQL function with the type you want to coerce a value to, e.g.
CREATE FUNCTION foo(float8) RETURNS float8 AS 'SELECT $i' LANGUAGE SQL;
Any value provided to that function will be coerced to that value:
SELECT foo(12);
Even explicitly specifying the type will work:
SELECT foo(12::numeric);
Your C code will receive a double. (Credit goes to Tom Lane, see this mailing list post.)
Both operands of * must have arithmetic type (integer or floating-point types). It's a pretty good bet that Numeric is a typedef for something that isn't a simple integer or floating-point type.
Unfortunately, I don't know enough about the Postgres API to be much more help. Hopefully there's a macro or a function that can either convert a Numeric to an arithmetic type, or apply an arithmetic operation to a Numeric type.
#include "utils/numeric.h"
// ....
Numeric p = PG_GETARG_NUMERIC(0);
Numeric b = int64_div_fast_to_numeric(5, 1); // 0.5
bool failed = false;
Numeric r = numeric_mul_opt_error(p, b, &failed);
if (failed) {
// handle failure here
}
PG_RETURN_NUMERIC(r);

Can you create an integer custom field in Salesforce.com?

I want to create an integer custom field on an object. I see that I can create a custom field of "Number" but that seems to return a decimal type. Mostly this is annoying as I plan to use the field as an Integer and everywhere I'm using it in code I have to cast it to an Integer. None of the other field types seem to be even close - the only other field type that even seems to hold a numeric type is Currency.
I've adjusted the number after the decimal fields to (3,0) - three numbers before the decimal, zero numbers after the decimal. It's still returning a decimal.
Is it even possible to create an integer? Is casting it every time I need it considered the "best practice"?
You can't create an integer type. As you've discovered, Number results in a decimal. If you'd like to treat it as an integer you just cast it.
If you're using the field in Visualforce, make sure you use <apex:outputField> or <apex:inputField>, as opposed to <apex:outputText> and <apex:inputText>, which will render out the decimal place. Ran into this issue not long ago.

Resources