BizTalk 2013 WCF-SQL adapter to insert into decimal(38,20) - biztalk

I am having problems inserting values into SQL Server columns of type decimal(38, 20) from BizTalk 2013 using WCF-SQL adapter. I get InvalidCastException with message: "System.InvalidCastException: Specified cast is not valid"
If I test column type decimal(18,18) it works.
Seems like the WCF-SQL adapter does not handle decimal with very high precision. Question is what is the limitation? And, if there is a workaround?
When I generate XSD from database table information, decimal(38,20) turns into xs:string with length restriction of 40. Maybe this is a sign of that WCF-SQL adapter cannot handle such precision...? I have also tested to alter the XSD to be xs:decimal, but no difference.
Anyone?
ADDITION:
Did not find any "good" way to handle this limitation.
Final setup is: XML => WCF-SQL adapter => Stored Procedure with table type parameter containing varchar(40) columns => CAST table variable columns to decimal(38,20) one-by-one => INSERT into destination table.
So, solution was to modify table type to accept varchar, and manually convert in stored procedure.
Would be happy if someone could explain the better solution!

Decimal precision is limited to the .NET framework type. See here.
Also described in the BizTalk documentation here. "Decimal if precision <= 28. String if precision > 28".
So your way of handling with strings is an option. Use the Round functoid in your map to the SQL schema if you don't really need more than 29 positions.
Another option you could consider is changing the regional settings for the BizTalk host user running the send port. The current setting/language of your decimal separator is a comma instead of a dot (or the other way around) and not matching the data type for SQL Server. For this option you have to keep the type as string in your schema and keep it decimal in your SQL Server table.

Related

How to implement INSERT where not exists for ORACLE in Mule4

I am trying to implement a use-case in Mule4 where a tour needs to be assigned to a user if it has not already been assigned.
I was hoping that I could implement it using Mule db:insert component and using INSERT WHERE NOT EXISTS SQL script as below.
INSERT INTO TL_MAPPING_TOUR(TOURNO,TLID,SYSTEM) select :tourno,:tlid,:system from DUAL
where not exists(select * from TL_MAPPING_TOUR where (TOURNO=:tourno and TLID=:tlid and SYSTEM=:system))
However, this is resulting in Mule Exception
Message : ORA-01722: invalid number
Error type : DB:BAD_SQL_SYNTAX
TL_MAPPING_TOUR table has an id column (Primary Key), but that is auto-generated by a sequence.
The same script, modified for running directly in SQL developer, as shown below, is working fine.
INSERT into TL_MAPPING_TOUR(TOURNO,TLID,SYSTEM)
select 'CLLO001474','123456789','AS400'
from DUAL
where not exists(select * from TL_MAPPING_TOUR where (TOURNO='CLLO001474' and TLID='123456789' and SYSTEM='AS400'));
Clearly Mule db:insert component doesn't like the syntax, but it's not very clear to me what is wrong here. I can't find any INSERT WHERE NOT EXISTS example implementation for the Mule4 Database component either.
stackoverflow page https://stackoverflow.com/questions/54910330/insert-record-into-sql-server-when-it-does-not-already-exist-using-mule directs to page not found.
Any idea what is wrong here and how to implement this in Mule4 without using another Mule4 db:select component before db:insert?
I don't know "mule4", but this:
Message : ORA-01722: invalid number
doesn't mean that syntax is wrong (as you already tested it - the same statement works OK in another tool).
Cause: You executed a SQL statement that tried to convert a string to a number, but it was unsuccessful.
Resolution:
The option(s) to resolve this Oracle error are:
Option #1: Only numeric fields or character fields that contain numeric values can be used in arithmetic operations. Make sure that all expressions evaluate to numbers.
Option #2: If you are adding or subtracting from dates, make sure that you added/substracted a numeric value from the date.
In other words, it seems that one of columns is declared as NUMBER, while you passed something that is a string. Oracle performed implicit conversion when you tested the statement in SQL Developer, but it seems that mule4 didn't and hence the error.
The most obvious cause (based on what you posted) is putting '123456789' into TLID as other values are obviously strings. Therefore, pass 123456789 (a number, no single quotes around it) and see what happens. Should work.
SQL Developer is too forgiving. It will convert string to numbers and vise versa automatically when it can. And it can a lot.
Mulesoft DB connector tries the same but it is not as succefule as native tools. Pretty often it fails to convert, especially on dates but this is not your case.
In short - do not trust too much data sense of Mulesoft. If it works - great! Otherwise try to eliminate any intelligence from it and do all conversions in the query and better from the string. Usually number works fine but if doesn't - use to_number function to mark properly that this is the number.
More about this is here https://simpleflatservice.com/mule4/AvoidCoversionsOrMakeThemNative.html

Oracle DB vs Mariadb

I have to find out in MariaDb how to implement some features used in Oracle . I have :
Load a file: in Oracle I use the external table. Is there a way (fast and efficient one ) to load a file into a table . Has MariaDb a plugin which allows to load well a specific format of files?
In my existing Oracle code I used to developp a java wrap functions which allow those feature (is there a way in MariaDb to do this?), specifically :
1- Searching a files in an OS directory and insert them in a table,
2- send an SNMP trap
3- Send a mail via SMTP
Is there an equivalent to an Oracle job in Mariadb?
Is there an equivalent to Oracle TDE (Transparent data encryption) ?
Is there an equivalent to the VPD (virtual private policy)?
What is the maximum length of a varchar column/variable ? (in Oracle we can use the CLOBs..)
Many Thanks and Best Regards
MariaDB (and MySQL) can do a LOAD DATA on a CSV file. It is probably the most efficient way to convert external data to a table. (There is also ENGINE=CSV, which requires no conversion, but is limited in that it has no indexes, etc.)
MariaDB cannot, for security reasons, issue any arbitrary system calls. No emails, no 'exec', etc.
No Job, TDE, VPD.
Network transmissions can (optionally) use SSL for encryption at that level.
There is a family of virtually identical datatypes for characters:
CHAR(n), VARCHAR(n) -- where n is up to 65535; n is the limit of _characters_, not _bytes_.
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT -- of various limits; the last is limited to 4GB.
For non-character storage (eg, images), there is a similar set of datatypes
BINARY(n), VARBINARY(n)
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
The various sizes of TEXT and BLOB indicate whether that is a 1-, 2-, 3-, or 4-byte length field in the implementation.
NVARCHAR is a synonym for VARCHAR. Character sets are handled by declaring a column to be, for example, CHARACTER SET utf8 COLLATE utf8_unicode_ci. Such can be defaulted at the database (schema) level, defaulted at the table level, or specified differently for different columns (even in the same table).

InvalidCastException for LINQPAD

I'm using LinqPad and IQ driver for SQLite. I have connection with this file. Look:
"Okreslone rzutowanie jest nieprawidlowe" - it can be simple translate to "invalid cast", but Zbiors.Count() return value 8.
When i'm trying do it in SQL query:
select * from zbior
Then all's ok. How can i get same result by "C#", not by SQL query?
Most likely, the types are incorrect. SQLite has a horrible "feature" whereby you can put strings into integer columns and vice versa. The column types are merely suggestion and are not enforced. So what looks like integers in your data might actually be strings, causing in InvalidCastException when the IQ driver tries to read them.

How to convert Number Datatype to Text Datatype - ODBC Query - C#

I am developing a Windows Forms Application in C# with 2.0 being the underlying .Net Framework. I use .Net Framework Data Provider for ODBC in order to connect to a specific access database.
I have a field say "NumberColumn" with 'Number' datatype & another field say "StringColumn" with 'Text' datatype in one of the tables present in the database. I have to concatenate the values present in the two fields in this format ("StringColumn-NumberColumn").
I tried using the convert function "CStr" in the query to convert the number column and append with the string column but am getting an exception "Invalid scalar function CStr".
Presently, am doing this concatenation in the DataTable level which I feel is expensive considering the huge amount of data. How could I achieve the concatenation in the specified format while querying the data?
I don't think you mention the database but I would expect something like
select StringColumn || '-' || cast( NumberColumn as varchar ) from table
may do what you want, but that becomes database dependent.
If you are saying its access, and you are using the jet provider then I would think that
select StringColumn + '-' + {fn cstr( NumberColumn )} from table
Would work. At least it does directly to the MS Access ODBC driver

BizTalk Database Lookup functoid fixed condition

Is there a way to further restrict the lookup performed by a database lookup functoid to include another column?
I have a table containing four columns.
Id (identity not important for this)
MapId int
Ident1 varchar
Ident2 varchar
I'm trying to get Ident2 for a match on Ident1 but wish it to only lookup where MapId = 1.
The functoid only allows the four inputs any ideas?
UPDATE
It appears there is a technique if you are interested in searching across columns that are string data types. For those interested I found this out here...
Google Books: BizTalk 2006 Recipes
Seeing as I wish to restrict on a numberic column this doesn't work for me. If anyone has any ideas I'd appreciate it. Otherwwise I may need to think about my MapId column becoming a string.
I changed the MapId to MapCode of type char(3) and used the technique described in the book I linked to in the update to the original question.
The only issue I faced was that my column collations where not in line so I was getting an error from the SQL when they where concatenated in the statement generated by the map.
exec sp_executesql N'SELECT * FROM IdentMap WHERE MapCode+Ident1= #P1',N'#P1 nvarchar(17)',N'<MapCode><Ident2>'
Sniffed this using the SQL Profiler

Resources