Database Connectivity using Linked Server. (Numeric Values) - sql-server

So I established a connection from my SQL Server 2008 Express Edition to our Oracle Database.
When I query varchar based values, it is fine, but for any numeric value, it throws me an error like this one.
Msg 9803, Level 16, State 1, Line 1
Invalid data for type "numeric".
How do I get around this?

I've run into this myself. Your error is caused by Number fields not being properly handled by the linkage. The easiest fix is to cast to a varchar inside your OPENQUERY, and to cast back to a number on the other side
SELECT CONVERT(INT, YourField ) AS YourField
FROM OPENQUERY (LINKEDSERVER,
'SELECT TO_CHAR(YourField ) AS YourField FROM RemoteTable');

Maybe this helps...
http://msdn.microsoft.com/en-us/library/ms151817.aspx

One individual said that they found the answer in Oracle's Metalink DocID 369814.1. They said the solution is to install an Oracle OLEDB driver with minimum version 10.2.0.2.20.
They installed an Oracle client 10.2.0.3 and then applied the applicable patch (described in the Metalink DocID 369814.1).
I found this post at http://forums.oracle.com/forums/thread.jspa?threadID=337842&start=15&tstart=135.
This seems like a better solution than converting to a char datatype, then converting back to a numeric datatype. I assume that those conversions will cost you in performance.

We had the same problem in one of our environments and the problem was that we had set up the linked server incorrectly.
We changed it to Microsoft OLD DB Provider for Oracle and the problems was resolved. Hope this helps.

Related

IS NOT NULL AS ... - Convert Query from MySQL to MS-SQL

I have an application that is working fine using a MySQL/MariaDB-Database.
I did make it more flexible and now I am basically able to use a Microsoft SQL-Server database.
I found out, that some SQL-queries do NOT work anymore.
I don't have experience with MS-SQL and I am looking for support to convert the following query to make it work with MS-SQL. It would be great, if the query could be converted to work in both MS-SQL and MySQL ...
I have created an SQL-Fiddle with some example-data.
Link: http://sqlfiddle.com/#!18/5fb718/2
The Query itself looks like this:
SELECT computermapping.PrinterGUID, computerdefaultprinter.PrinterGUID IS NOT NULL AS isDefaultPrinter
FROM computermapping
LEFT JOIN computerdefaultprinter ON computerdefaultprinter.ComputerGUID = computermapping.ComputerGUID
AND computerdefaultprinter.PrinterGUID = computermapping.PrinterGUID
WHERE computermapping.ComputerGUID = "5bec3779-b002-46ba-97c4-19158c13001f"
When I run this on SQL-Fiddle I get the following error:
Incorrect syntax near the keyword 'IS'.
When I run this Query in Microsoft SQL Server Management Studio I get the same Error. I have an German-Installation ...
Meldung 156, Ebene 15, Status 1, Zeile 1
Falsche Syntax in der Nähe des IS-Schlüsselworts.
I was looking on the Internet to find information on how to use the IS NOT NULL AS in MS-SQL. Maybe I was using the wrong keywords, but I was not able to find a solution myself.
If it does matter, I am using "SQL-Server 2014 SP3" at the moment.
Thank you
Convert
computerdefaultprinter.PrinterGUID IS NOT NULL AS isDefaultPrinter
to
CASE
WHEN computerdefaultprinter.PrinterGUID IS NOT NULL THEN 1
ELSE 0
END AS isDefaultPrinter
Demo here
Also bear in mind that there is no BOOLEAN type in SQL Server. BIT type is used instead.
Finally
WHERE computermapping.ComputerGUID = "5bec3779-b002-46ba-97c4-19158c13001f"
should be converted to
WHERE computermapping.ComputerGUID = '5bec3779-b002-46ba-97c4-19158c13001f'
since the single quote character is used to delimit strings in SQL Server
MySql evaluates boolean expressions like:
computerdefaultprinter.PrinterGUID IS NOT NULL
as 1 for TRUE or 0 for FALSE.
SQL Server does not do such an evaluation, so you need a CASE expression:
CASE WHEN computerdefaultprinter.PrinterGUID IS NOT NULL THEN 1 ELSE 0 END
The exact question was already answered, but you should really, really try using the SQL Server Migration Assistant for MySQL. No database supports the SQL standard beyond a basic compatibility level and MySQL is one of the quirkiest databases when it comes to SQL compatibility.
The SQL standard process is sloooow so all vendors implement features long before they're standardized. Different databases have different priorities too, and MySQL's priority for the first decade at least wasn't enterprise applications, so SQL compatibility wasn't a high priority.
Some common features were added only in MySQL 8. Some hacks allowed (but discouraged) in MySQL, like non-aggregate columns in a grouping query, or quirky updates to calculate row numbers, don't work in any other databases because logically, they lead to unpredictable results.
Even in MySQL, non-aggregate columns can cause serious performance degradation when upgrading from one 5.x version to the next. There's at least one SO question about this.
The Migration assistant will convert tables and types where possible and flag any stored procedure or view queries that can't be translated. It can also copy data from an existing MySQL database to a SQL Server database

SQL Server 2019 CHARINDEX returns weird result

When I run the following query in SQL Server 2019, the result is 1, whereas it should be 0.
select CHARINDEX('αρ', 'αυρ')
What could be the problem?
As was mentioned in the comments it may be because you have not declared your string literals as Unicode strings but are using Unicode characters in the strings. SQL Server will be converting the strings to another codepage and doing a bad job of it. Try running this query to see the difference.
SELECT 'αρ', 'αυρ', N'αρ', N'αυρ'
On my server, this gives the following output:
a? a?? αρ αυρ
Another issue is that CHARINDEDX uses the collation of the input which I think is probably not set correctly in this instance. You can force a collation by setting it on one of the inputs. It is also possible to set it at the instance, database and column level.
There are different collations that may be applicable. These have different features, for example some are case sensitive some are not. Also not all collations are installed with every SQL Server instance. It would be worth running SELECT * from sys.fn_helpcollations() to see the descriptions of all the installed ones.
If you change your query to this you should get the result you are looking for.
SELECT CHARINDEX(N'αρ' COLLATE Greek_BIN, N'αυρ')

Select from IBM DB2 using Openquery() and member

I want to fetch some data from an IBM DB2 server using SQL Server 2008.
For this I have tried to use:
SELECT * From Openquery(LINKED_SRV,'Select * from dta.Filename')
which gives me data, albeit rather old data.
I have since gathered that the updated data is in another Member on the server, and that the default member is the outdated one I tried to import data from.
I am told the current Member is PROD2017. I have read some IBM DB2 documentation where a Library.Filename(Member) convention is used, but using:
SELECT * From Openquery(LINKED_SRV,'Select * from dta.Filename(PROD2017)')
but this gives me an error that ( is not supported.
Of several attempts which has failed I have also tried to use:
SELECT * From Openquery(LINKED_SRV,'Select * from dta.Filename"(PROD2017)"')
which actually gives a result set, but it is the same result set as the original one omitting the membership, so I'd reckon there is some issue with the Query either way.
How can I find data using openquery() from an IBM DB2 server using Sql server, when the DB2 server uses membership?
Cenderze,
From my SQL server I can query my DB2 machine through a linked server without OPENQUERY. For example:
select t1.ordno from LinkedServer.Database.Library.Table t1
Note the use of aliasing and the 4-part identifier. Replace these with your specifics and let me know what happens.
M
I received a Notable Question award for this question today and I saw that it doesn't answer how I got this issue solved.
Mind you, this is a 3 year old question so my specifics may be a little bit off but I remember it as the following:
I queried a member for all production of 2017, called PROD2017
I understood this as a book analogy, where PROD2017 was the name of the book and that my query returned a chapter. For me, the query returned the wrong chapter (I believe January's sales or something where I wanted August's).
I told the company responsible for the data in the IBM DB2 connection and they had to redo their "sorting of the book", so that the query would return the correct month's data.
I believe they had to do this each month, but once again I'm iffy on the details seeing as how long ago this was.
Hopefully this can help someone, though :)

Why is this Sql Geography "Valid" on SQL Server 2014 and "Invalid" on Azure SQL?

Here's the query. Sorry it's in a paste-bin link and not in this question, but the geography data is longer than the maximum characters for the question!
http://pastebin.com/i0t1sqQR
There's two versions of the query there.
The first is the normal query, it runs fine on 2014, but on Azure Sql I get:
Msg 6522, Level 16, State 1, Line 11
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.ArgumentException: 24200: The specified input does not represent a valid geography instance. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a spatial instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeography..ctor(GeoData g, Int32 srid)
at Microsoft.SqlServer.Types.SqlGeography.GeographyFromBinary(OpenGisType type, SqlBytes wkbGeography, Int32 srid)
The second version is with .MakeValid() added. Again it runs fine on 2014, but I get the exact same error again on Azure Sql.
Why is this behaving differently?
Why doesn't MakeValid() work?
As a side note ... where is the documentation for the differences between Sql Server and Azure Sql?
I've found a blog post from 2014: http://blogs.msdn.com/b/rbrundritt/archive/2014/08/18/working-with-invalid-geography-objects-in-sql-azure.aspx
That references patch notes form 2011: http://social.technet.microsoft.com/wiki/contents/articles/6197.updated-spatial-features-in-the-sql-azure-q4-2011-service-release.aspx
So MakeValid was shown in the table in the article as working, but had a note saying "actually this doesn't work at all" and that was the only indication of that issue for 3 years?
The short answer is that the first geography isn't valid in either case (i.e. on premises SQL or Azure). If I take the code from your pastebin link and transform it slightly to:
exec sp_executesql N'
DECLARE #Location geography = geography::STGeomFromWKB(#wkb, 4326);
SELECT #Location.STIsValid()
',N'#wkb varbinary(max)',#wkb=0x0106...
I get back 0 (i.e. false). That said, I don't know why the on prem version of SQL is able to display the first geography instance; typically a precondition for that is that it's valid.
If this is a one-time operation, maybe using the seemingly less restrictive on prem version to generate a valid geography which you can then export to Azure will work for you.

String concatenation in custom DBMS producing strange results

When trying a simple CONCAT I am getting syntax errors. The connection uses a proprietary ODBC driver, which I'm sure is the issue, but want to know if there is anything I can do from my end. The following is the query I initially tried:
SELECT CONCAT('DF', '01', ServiceCode) AS RecordID
FROM ServiceCodes
However this throws a syntax error near , ServiceCode, no other information. So I tried:
SELECT 'DF' + '01' + ServiceCode AS RecordID
FROM ServiceCodes
But this returns the error term_expr type not supported which I assume is a specific error from the driver.
So then I tried:
SELECT CONCAT(CONCAT('DF', '01'), ServiceCode) AS RecordID
FROM ServiceCodes
Which seems to have worked! Returning a string like DF01MOT. This works across all servers and so I added extra fields producing the query:
SELECT CONCAT(CONCAT('DF', '01'), ServiceCode) AS RecordID, 'DF' AS Environment
FROM ServiceCodes
This also seems to have worked, except on 1 server. When running the above query on this one server it will now return DF0DFMO instead of DF01MOT, last 2 chars change in each row depending on ServiceCode, adding further fields changes this again such as:
SELECT CONCAT(CONCAT('DF', '01'), ServiceCode) AS RecordID, 'DF' AS Environment, '01' AS SO
FROM ServiceCodes
This returns DF0DF01 for this field in ALL rows.
So why would this be happening? Why is it only on one server? Driver is the same on all servers but is this an issue with the driver? What can I do to get around it?
EDIT: To avoid confusion I have modified the title and tags. This is actually accessing a custom DBMS provided by a third party from with a DTS package in SQL Server Enterprise Manager. I do believe contacting the third party is the only option.
Having seen your comments, the SQL Server tag is actually a bit misleading here. You are running on a vendor DB using their driver. Clearly their DB supports a CONCAT function that only takes two arguments, rather than the SQL Server 2012 function which can take more. That explains your first issue.
As for the other results you are seeing lower down, you'd need to raise this with the vendor. The version of SQL Server you're using for DTS doesn't really have any relevance here.

Resources