IDataRecord.IsDBNull causes an System.OverflowException (Arithmetic Overflow) - c#

I have a OdbcDataReader that gets data from a database and returns a set of records.
The code that executes the query looks as follows:
OdbcDataReader reader = command.ExecuteReader();
while (reader.Read())
{
yield return reader.AsMovexProduct();
}
The method returns an IEnumerable of a custom type (MovexProduct). The convertion from an IDataRecord to my custom type MovexProduct happens in an extension-method that looks like this (abbrev.):
public static MovexProduct AsMovexProduct(this IDataRecord record)
{
var movexProduct = new MovexProduct
{
ItemNumber = record.GetString(0).Trim(),
Name = record.GetString(1).Trim(),
Category = record.GetString(2).Trim(),
ItemType = record.GetString(3).Trim()
};
if (!record.IsDBNull(4))
movexProduct.Status1 = int.Parse(record.GetString(4).Trim());
// Additional properties with IsDBNull checks follow here.
return movexProduct;
}
As soon as I hit the if (!record.IsDBNull(4)) I get an OverflowException with the exception message "Arithmetic operation resulted in an overflow."
StackTrace:
System.OverflowException was unhandled by user code
Message=Arithmetic operation resulted in an overflow.
Source=System.Data
StackTrace:
at System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
at System.Data.Odbc.OdbcDataReader.IsDBNull(Int32 i)
at JulaAil.DataService.Movex.Data.ExtensionMethods.AsMovexProduct(IDataRecord record) [...]
I've never encountered this problem before and I cannot figure out why I get it. I have verified that the record exists and that it contains data and that the indexes I provide are correct. I should also mention that I get the same exception if I change the if-statemnt to this: if (record.GetString(4) != null). What does work is encapsulating the property-assignment in a try {} catch (NullReferenceException) {} block - but that can lead to performance-loss (can it not?).
I am running the x64 version of Visual Studio and I'm using a 64-bit odbc driver.
Has anyone else come across this? Any suggestions as to how I could solve / get around this issue?
Many thanks!

For any one experiencing the same issue, the way I solved this was to switch from the Odbc* classes to their OleDb* counterparts. This of course demands that your data driver has support for OleDb connections.

Which DB are you trying to talk to? If it uses some "private" column types that can cause problems. That doesn't apply to SQL Server of course :-)
Also check that you are compiling and running as x64 (Process Explorer will show you thsi and even plain tack manager shows it). devenv.exe will still be x86 but your actual binary should run as x64. The reason I mention is that crossing 32/64 bit boundary is notorious for breaking 3rd party ODBC drivers.

Related

The type initializer for 'System.Data.SqlClient.TdsParser' threw an exception error while calling Stored Procedure from Azure function

I have an Azure Event hub with readings from my smart electricity meter. I am trying to use an Azure Function to write the meter readings to an Azure SQL DB. I have created a target table in the Azure SQL DB and a Stored Procedure to parse a JSON and store the contents in the table. I have successfully tested the stored procedure.
When I call it from my Azure Function however I am getting an error: The type initializer for 'System.Data.SqlClient.TdsParser' threw an exception. For testing purposes, I have tried to execute a simple SQL select statement from my Azure Function, but that gives the same error. I am lost at the moment as I have tried many options without any luck. Here is the Azure function code:
#r "Microsoft.Azure.EventHubs"
using System;
using System.Text;
using System.Data;
using Microsoft.Azure.EventHubs;
using System.Data.SqlClient;
using System.Configuration;
using Dapper;
public static async Task Run(string events, ILogger log)
{
var exceptions = new List<Exception>();
try
{
if(String.IsNullOrWhiteSpace(events))
return;
try{
string ConnString = Environment.GetEnvironmentVariable("SQLAZURECONNSTR_azure-db-connection-meterreadevents", EnvironmentVariableTarget.Process);
using(SqlConnection conn = new SqlConnection(ConnString))
{
conn.Execute("dbo.ImportEvents", new { Events = events }, commandType: CommandType.StoredProcedure);
}
} catch (Exception ex) {
log.LogInformation($"C# Event Hub trigger function exception: {ex.Message}");
}
}
catch (Exception e)
{
// We need to keep processing the rest of the batch - capture this exception and continue.
// Also, consider capturing details of the message that failed to process so it can be processed again later.
exceptions.Add(e);
}
// Once processing of the batch is complete if any messages in the batch failed process throw an exception so that there is a record of the failure.
if (exceptions.Count > 1)
throw new AggregateException(exceptions);
if (exceptions.Count == 1)
throw exceptions.Single();
}
The events coming in are in JSON form as follows
{
"current_consumption":450,
"back_low":0.004,
"current_back":0,
"total_high":13466.338,
"gas":8063.749,
"current_rate":"001",
"total_low":12074.859,
"back_high":0.011,
"timestamp":"2020-02-29 22:21:14.087210"
}
The stored procedure is as follows:
CREATE PROCEDURE [dbo].[ImportEvents]
#Events NVARCHAR(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Insert statements for procedure here
INSERT INTO dbo.MeterReadEvents
SELECT * FROM OPENJSON(#Events) WITH (timestamp datetime2, current_consumption int, current_rate nchar(3), current_back int, total_low numeric(8, 3), back_high numeric(8, 3), total_high numeric(8, 3), gas numeric(7, 3), back_low numeric(8, 3))
END
I have added a connection string of type SQL AZURE and changed {your password} by the actual password in the string. Any thoughts on how to fix this issue or maybe how to get more logging as the error is very general?.
I managed to fix this exception by re-installing Microsoft.Data.SqlClient.SNI. Then clean and rebuild your project.
I managed to fix the issue by changing the Runtime version to ~2 in the Function App Settings.
Does this mean this is some bug in runtime version ~3 or should there be another way of fixing it in runtime version ~3?
I might be late to the party, in my case the cause of the error was "Target runtime" when publishing, I developed on windows machine but was transferring the file to linux, the solution was to change target runtime to the correct one, initial it was win-x64(merely because I started off by deploying locally), see screenshot below
Try to connect to a local SQL, use SQL profiler, and check what you are sending, and what precisely SQL is trying to do with the command being executed.
It's very hard to replicate your code, because, I obviously do not have your Azure SQL :)
So I would suggest, try to execute each step in the Stored procedure, as direct queries.
See if that works, then try to wrap the statements into store-procedures called back-to-back, and get that to work.
Then combine the commands to a single command, and fiddle with it till you get it to work ;)
Get the most simple query to execute towards the Azure SQL, so you are sure your connection is valid. (Like just a simple select on something)
Because without more information, it is very difficult to assist you.
Pretty silly but I got this after installing the EntityFrameworkCore Nuget package but not EntityFrameworkCore.SqlServer Nuget package. I had the SqlServer version for EntityFramework 6 installed.
I had the same error with a VSTO-application that was installed with a double click in the file explorer. Windows copied not all files to such an automatic location somewhere into ProgramData, so the application was simply not complete!
The solution was to register the VSTO-application manualy in HKEY_CURRENT_USER and pointed the "Manifest" to the complete directory with all the files. (like Microsoft.Data.SqlClient.dll, Microsoft.Data.SqlClient.SNI.x64.dll etc)
Those automatically by Windows chosen installations/directories will give unexpected behaviour. :(
Some ws methods ran fine and other would fail with this same error. I ran ws method that was failing in the browser on the box that the ws was being served from and got a lengthy, and helpful error message. One item was an InnerException that said
<ExceptionMessage>Failed to load C:\sites\TXStockChecker.xxxxxx.com\bin\x64\SNI.dll</ExceptionMessage>
I noticed that that file was right were it was expected in my development environment so I copied it to the matching directory on the prod ws and now all the methods run as expected.

Accessing member of Microsoft.SqlServer.Management.Smo.Server object crashes exactly once

We are trying to access the DefaultFile member of an Microsoft.SqlServer.Management.Smo.Server object. After a lot of debugging, it turns out that accessing the member crashes the first time, but can then be accessed just fine. Looking at the variable in a debug window returns an exception the first time, the correct value the second and all following times.
The first access of either server.DefaultFile or server.DefaultLog throws an exception like this:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Microsoft.SqlServer.Management.Smo.BitStorage.SetBit(Int32 itemIndex, BitIndex bitIndex, Boolean value)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.SetRetrieved(Int32 index, Boolean val)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.AddObjectPropsFromDataReader(IDataReader reader, Boolean skipIfDirty, Int32 startColIdx, Int32 endColIdx)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ImplInitialize(String[] fields, OrderBy[] orderby)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.Initialize(Boolean allProperties)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String propname, Boolean useDefaultValue)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue)
at Microsoft.SqlServer.Management.Smo.Server.get_DefaultFile()
at my function... etc etc
The first-access-crash is very concistent, so doing something terrible like below gets around the problem completely:
using (var sqlConnection = new SqlConnection(sourceDatabaseConnectionString.ConnectionString))
{
var svrConnection = new ServerConnection(sqlConnection);
var server = new Server(svrConnection);
// begin mega hack
try
{
// crashes on first access
var dummy = server.DefaultFile;
}
catch
{
// do absolutely nothing
}
// end mega hack
// business as usual...
var defaultFile = server.DefaultFile;
}
Of course, we don't like code like this (even if it's only in our internal tools) so any ideas of why this might be happening is welcome. Our only clue is that we've recently upgraded some instances of SQL Server 2012 to SQL Server 2014. We can sometimes get around the issue when running the code locally on a machine with SQL Server 2014 installed. The production machine that runs this code does not have an installation at all, but references DLLs. However, we can't find any differences in the versions used when debug printing the assembly versions while running the code.
I've seen similar messages when using an older version of SMO, especially when trying to use 2008R2 SMO to access 2012. Upgrading to the installs from 2008R2 Featurepack SP3 fixed my issues.
Check that there's not a more recent version of the Shared Management Objects + CLR Types + Native client driver that you could use.

DbGeography.PointFromText error Exception has been thrown by the target of an invocation

I am starting my first project using spacial data. Im using VS 2012 and SQL 2012 I have referenced System.Data.Entity and can use DbGeography in my code but when I try to create a point I get the above error and don't understand why
here is my code
var text = string.Format(CultureInfo.InvariantCulture.NumberFormat,
"POINT({0} {1})", submitted.Long, submitted.Lat);
// 4326 is most common coordinate system used by GPS/Maps
try
{
var wkb = DbGeography.PointFromText(text, 4226);
}
catch (Exception exc)
{
}
the syntax that OP has used is correct, the actual issue that caused this error was the SRID, 4226 is not a known SRID, But you already knew this. because it is in your comment :)
A one line example of the correct usage in your scenario would be:
var wkb = DbGeography.PointFromText($"POINT({submitted.Long} {submitted.Lat})", 4326);
Where did you go wrong though? Whenever you get a
System.Reflection.TargetInvocationException
With a message of
Exception has been thrown by the target of an invocation
You must immediately check the Inner Exception for the details on the actual error, in this case it is outlined clearly for you:
24204: The spatial reference identifier (SRID) is not valid. The specified SRID must match one of the supported SRIDs displayed in the sys.spatial_reference_systems catalog view.
I realise that this is an old thread, but IMO this is an example of second most common .Net developer issue that people keep posting on SO. Please read through your full exception stack before pulling your hair out.
I'm just guessing, but I reckon NullReferenceException issues would be the most common :)
is wrong to order the lat and long
the correct is:
DbGeography.PointFromText(POINT(lat long), 4226);
Complete class:
public static DbGeography CreatePoint(double latitude, double longetude, int srid = 4326)
{
var lon = longetude.ToString(CultureInfo.InvariantCulture);
var lat = latitude.ToString(CultureInfo.InvariantCulture);
var geo = $"POINT({lat} {lon})";
return DbGeography.PointFromText(geo, srid);
}
Call:
CreatePoint(-46.55377, 23.11817)

Refrences break console app from running on other machines

I've made a console application which inserts data into a MySql backend, and reads the serial number from a hard disk
To do this i had to add References to MySql.Data and to System.Managment.
The way im running it is by copying the Debug directory from visual studio (i think this is the problem) and running the .exe file on the other machine.
When i run the application on another machine the stack trace error is:
PhDD >C:\Users\User\File\Indexer\WMI\Debug
Your key: 634685018347902535133
Exception getting SMART Object: reference not set to an instance of an object.
Exception in main thread: at System.ThrowHelper.ThrowArgumentOutOfRangeExcept
ion()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at WMITest.Menu.Run() in C:\Users\fps700\Music\WMITest\Menu.cs:line 49
Updated HDD Stats at28/03/2012 18:46:57
Am i correct in thinking this problem is because of the referencing ?
I've checked the methods by recompiling the same code on the other machine and it works, when the references are added through VS.
Can anyone guide me on how to resolve this issue ?
Cheers for reading.
P.S. i tried adding reference paths (by right clicking on the project, selecting options and then choosing Reference Paths and adding the two dll files)
Line 49
bool conversion = int.TryParse(smartData[1].ToString(), out temp);
After adding a fake int value just to make sure conversion isnt the error the new stack trace error is:
PhDD >C:\Users\bborisov\Dropbox\Indexer\WMI\Debug
Your key: 634685018347902535133
Exception getting SMART Object reference not set to an instance of an object.
Exception in main thread: at System.ThrowHelper.ThrowArgumentOutOfRangeExcept
ion()
at System.Collections.Generic.List`1.get_Item(Int32 index)
at WMITest.Menu.Run() in C:\Users\fps700\Music\WMITest\Menu.cs:line 53
Updated HDD Stats at28/03/2012 19:00:24
line 53:
DBHandler.insertData(smartData[0].Trim(),
3, smartData[2], file.getKey());
Put code in to check validity of error situations which may be happening on the client pc but not the development one. You can handle the errors by either throwing an exception or handling it gracefully in a better way.
Here is the code which checks for error situations
if (smartData == null)
throw new Exception("Smart data is null; aborting");
if (smartData.Any() == false)
throw new Exception("Smart data instance is valid but has no elements; aborting");
bool conversion = int.TryParse(smartData[1].ToString(), out temp);

Linq 'Index was outside the bounds of the array' problem

In trying to setup a unit test for inserting an item into an SQL Server Express (2008) database using C# Linq I've encountered an error that is causing me some trouble. The Linq code is built using Visual Studio 2008.
The exception is thrown on a system running Windows XP SP2. The Linq works fine and the record is inserted appropriately on a system running Windows 7 Home Premium (64-bit).
I've dropped and re-created the database on the XP system. I've dropped and re-created the DAL and corresponding DBML on the XP system.
Other tables with unit tests for inserts to the same database work just fine.
Inserting a record into the table using a simple insert statement in SQL Server Management Studio works appropriately.
What should I look at to find the source of the problem? What should be done to resolve the problem?
Any insight as to what the error message is really trying to say would be greatly appreciated.
Error Message
System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace
at
System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k)
at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues)
at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues)
at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues)
at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance)
at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at nUnit.DAL.FacilityTests.AddFacility2() in C:\SVN\SVNRevenue360\Branches\Dev\Code\ProviderAdvantage\nUnit.CoreTests\Tests\DAL\FacilityTests.cs:line 50
Insert Code
[Test]
public void AddFacility2() {
string facilityname = "Test Facility";
try {
using (PA.Database.Revenue360DB db = new PA.Database.Revenue360DB(PA.DAL.DataAccess.ConnectionString)) {
db.Log = Console.Out;
PA.Database.Facility facility = new PA.Database.Facility();
facility.id = Guid.NewGuid();
facility.Name = facilityname;
facility.Street1 = "";
facility.Street2 = "";
facility.Street3 = "";
facility.City = "";
facility.State = "";
facility.Zip = "";
facility.Description = "";
db.Facilities.InsertOnSubmit(facility);
db.SubmitChanges(); // line 50
}
} catch (Exception ex) {
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
Console.WriteLine(ex.InnerException == null ?
"No inner exception" :
ex.InnerException.GetType().FullName + ": " + ex.InnerException.Message);
throw;
}
}
I've looked at the following SO questions without insight as to what is causing this particular issue.
https://stackoverflow.com/questions/1087172/why-am-i-getting-index-was-outside-the-bounds-of-the-array
IndexOutOfRangeException on Queryable.Single
Strange LINQ Exception (Index out of bounds)
Take a look at this link.
Here are a few excerpts:
A common cause of this error is
associations pointing in the wrong
direction. (Something that is
extremely easy to do if editing the
model by hand, partly because the
association arrow pointer is in the
opposite end of where it would appear
in an ER diagram)
and
I was having the same problem and it
was due to the fact my primary key was
two columns instead of the traditional
one. (both guids). When I added a
third column that was the sole primary
key column, it worked.
UPDATE: Did some more poking around and found this SO post. Looks like it might have something to do with your DBML...
If the code is working on one machine and not working on another the problem should be somewhere outside. Please check if the .NET Framework version on Windows XP is the same as on Windows 7. Secondly, if its XP SP2 then the Operating System might be the cause because Microsoft has changed a lot in SP3. Also check if the database has same tables. Try to reproduce the problem on the same db, i.e. take backup from Win7 and restore it on the XP (of cause backup your data first). What else? Security permissions and connection string might have an impact too.

Categories

Resources