Receiving different SqlException in Windows service to expected - c#

I'm having a very strange issue. I have windows service which is failing because of a SqlException: "String or binary data would be truncated." for an INSERT statement.
Now this is a fairly basic error to solve but it is not the true error. If I do a trace and run the query straight on the database - there is NO error. All of the data in WAY shorter than the restrictions on the database.
I eventually took out some of this required columns from the query hoping to generate a different error: "Cannot insert the value NULL into column 'Type'"
I don't however get this error! I am still getting "String or binary data would be truncated."
I DO get this error if I run the query from the trace straight on the DB.
Does anyone have any ideas on what could be happening here? Thanks!
Edit to add
Here's the query that is supposed to give me the cannot insert value error. The other query is the same but with more parameters:
declare #p4 int
set #p4=60029550
exec sp_executesql N'EXECUTE ssl_GetTTDVersionCallSeq 1, #TTDVersionIDVal OUTPUT
INSERT INTO TTDVersion(Task,ID) VALUES (#P0,#TTDVersionIDVal)',N'#P0 int,#TTDVersionIDVal int output',#P0=200003762,#TTDVersionIDVal=#p4 output
select #p4

Found the cause of this error. It was not at all in the query posted above. There was a trigger on the table which set the LastUpdatedBy column.
Most of the users have a 4 char user name but the user that the service was being run as didn't. The column limit was 4.
Avoid this issue:
Triggers can be problematic. They aren't immediately visible - sp_help 'table' doesn't even return them. If they error you can't even trace the query.
What I should of tried earlier:
Running the query as the user. (I wanted to but it's an admin user and someone else was using it at the time.)
Checking all columns info vs what was in them and what was in the query. Then to check how that info is getting there. In this case a default constraint probably would of given same issue.

Related

Linq to sql unhandled exception from update stored procedure

I have a simple Linq dbml class, containing 1 table. First I have it configured to "Use runtime" to do the updates. Throgh the UI, I'm intentionally updating a column to a wrong value. Then calling dataContext.SubmitChanges throws an error, which is caught in a catch=block, showing a MessageBox "The UPDATE statement conflicted with the CHECK constraint ...", as it should. So, everything is fine.
Then I change the update behaviour to "Customize" and use a simple update stored procedure (just 1 simple update statement). Updating through the UI with correct values works like a charm. The update sproc is called and everything is fine. But when entering this wrong value through the UI, and then pressing update, I get an unhandled exception on this line of code (internal code of the Linq class):
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), field1, field2, ...);
Title: Exception User-Unhandled System.Data.SqlClient.SqlException:
'The UPDATE statement conflicted with the CHECK constraint
"CK_tblRitCentraal". The conflict occurred in database "RCS", table
"dbo.tblRitCentraal", column 'RitOpmerkingen'.
The statement has been terminated.'
Any help is greatly appreciated!
thanks for your reply. You are right, that my problem is, that the exception in yhe second case is not caught, even though it is exactly the same error as in the first case.
In the meantime I solved my problem. All I had to do was tick "do not break on this type of exceptions". Now the exception is nicely put through to the UI, and I can take care of it.
Still, I can't understand why. But hey, it got solved, so I shouldn't complain.

String Or Binary Data Would Be Truncated - Column is Big Enough

I have a confusing issue. I have a WPF application that is using a local SQL Server Database. I am using Entity Framework. I'm trying to store a byte array of length 120 into a BINARY(120) column.
The data should fit, but for some reason I keep getting the error, 'String or binary data would be truncated'.
The table structure looks like this:
Column_name Type Computed Length
Id int no 4
Foo varchar no 500
Bar binary no 120
As an experiment, I tried altering the column to be a VARBINARY(MAX) column, however even in that case I still get the same error. This would usually indicate that another column could be causing the problem, however I know the problem is not the Id column, and the string I'm storing into Foo is "test string", which is obviously small enough.
The method that is inserting into the database isn't doing anything special:
public void Create(FooEntry entry)
{
_context.FooEntries.Add(entry);
_context.SaveChanges();
}
Maybe I'm missing something really obvious, but how should I go about fixing this issue?
Update:
Yes, I am quite sure the EDMX and the database table is in sync (because when I update the database table, I always refresh the edmx).
I attempted to manually insert a byte array of length 120 into the table, and did not get the error. When I manually inserted a byte array of length 121, the 'String or binary data would be truncated' error occurred, which is the correct behavior.
The byte array that I was attempting to insert while debugging the program was this value:
'0x2400320061002400310030002400510078004400310072003400390079004C006D0041004A00760049004E005700730069007900490058004F007400740052007600500031006900700078004C0044007000610032004900350038007700310059002E0071003300680033004B0064002F00430074005700'
which is a byte array of length 120.
Update 2:
I ran SQL Server Profiler and it gave me the following SQL query:
exec sp_executesql N'INSERT [dbo].[FooEntry]([Foo], [Bar])
VALUES (#0, #1)
SELECT [Id]
FROM [dbo].[FooEntry]
WHERE ##ROWCOUNT > 0 AND [Id] = scope_identity()',N'#0 varchar(500),#1 binary(120)',#0='test string',#1=0x24003200610024003100300024004100420047007400560056006A0076004D006F006500770036005000300054004D002F006B007800740075007A00490036004F004400660047004A0062004E0069004E00790041007A0051006A0058004300660072007400360051007A0043004B004400580075006500
Very weird. This query works when I execute it manually, but EF throws an error when this query is executed while the program is running.
I have finally figured out the problem, and the answer is ridiculous.
There were two databases in my project directory, DatabaseA and DatabaseB that had the same schema. Entity Framework was running queries against DatabaseA, however my EDMX was pointing to DatabaseB, and the database that was showing in my Server Explorer was DatabaseB.
This issue probably occurred while I was fixing an issue I had earlier that was causing my local SQL Server database data to be overwritten with each build.
My advice for anybody that is running into this issue is to make sure your app.config files in your Solution all have connection strings that are pointing to the same database. The way I fixed this problem was to update the connection string in my data layer:
1) I removed the connection string in my app.config file
2) In my EDMX designer, I deleted my FooEntry table and then right-clicked and selected 'Update Model from Database'. Then a dialog popped up that allowed me to create a new connection string. Through this dialog, you can browse for the correct database and Visual Studio will make the correct connection string for you.

How can I make SQL Server 2012 truncate insertions if they are too big?

So I have a table with a column of type VARCHAR (100) and I'm wondering if there's a way to configure SQL Server 2012 (T-SQL) so that if a transaction tries to submit a string of 101+ characters then it takes the first 100.
Is this possible, or should I be doing the truncation in the C# side of things ???
Normally, SQL Server will present an error on any attempt to insert more data into a field than it can hold
String or binary data would be truncated. The statement has been terminated.
SQL Server will not permit a silent truncation of data just because the column is too small to accept the data. But there are other ways that SQL Server can truncate data that is about to be inserted into a table that will not generate any form of error or warning.
By default, ANSI_WARNINGS are turned on, and certain activities such as creating indexes on computed columns or indexed views require that they be turned on. But if they are turned off, SQL Server will truncate the data as needed to make it fit into the column. The ANSI_WARNINGS setting for a session can be controlled by
SET ANSI_WARNINGS { ON|OFF }
Unlike with an insert into a table, SQL Server will quietly cut off data that is being assigned to a variable, regardless of the status of ANSI_WARNINGS. For instance:
declare #smallString varchar(5)
declare #testint int
set #smallString = 'This is a long string'
set #testint = 123.456
print #smallString
print #testint
Results is:
This
123
This can occasionally show itself in subtle ways since passing a value into a stored procedure or function assigns it to the parameter variables and will quietly do a conversion. One method that can help guard against this situation is to give any parameter that will be directly inserted into a table a larger datatype than the target column so that SQL Server will raise the error, or perhaps to then check the length of the parameter and have custom code to handle it when it is too long.
For instance, if a stored procedure will use a parameter to insert data into a table with a column that is varchar(10), make the parameter varchar(15). Then if the data that is passed in is too long for the column, it will rollback and raise a truncation error instead of silently truncating and inserting. Of course, that runs the risk of being misleading to anyone who looks at the stored procedures header information without understanding what was done.
Source: Silent Truncation of SQL Server Data Inserts
Do this on code level. When you are inserting the current field check field length and Substring it.
string a = "string with more than 100 symbols";
if(a.Length > 100)
a = a.Substring(0, 100);
After that you are adding a as sql parameter to the insert query.
The other way is to do it in the query, but again I don't advice you to do that.
INSERT INTO Table1('YourColumn') VALUES(LEFT(RTRIM(stringMoreThan100symbols), 100))
LEFT is cutting the string and RTRIM is performing Trim operation of the string.
My suggestion would be to make the application side responsible for validating the input before calling any DB operation.
SQL Server silently truncates any varchars you specify as stored procedure parameters to the length of the varchar. So you should try considering stored procedures for you requirements. So it will get handled automatically.
If you have entity classes (not necessarily from EF) you can use StringLength(your field length) attribute to do this.

C# + MySQL + ExecuteNonQuery returns '1' on UPDATE but changes not in DB

i have a problem where i can't apparently find a solution even after hours of debugging.
I have a simple SQL command where i want to update a row with some value(the value is a text of about ~5mb), after executing the SQL Command, the 'ExecuteNonQuery()' on the C# code side, returns '1' and no exception but the changes are sometime reflected in the Database row and sometime not.
I tried debugging to see if the values that will replace the old one are correct and they are. I am using MySQL 5.5.11.
Could it be a MySQL setting or something?
Losing my mind on this problem, if you have any idea it would be greatly appreciated.
EDIT, include code:
The code is as simple as this:
cmd.CommandText = "UPDATE user SET data = #data WHERE id = #id";
then i add params to the DBCommand object for the SQL Query. The 'data' is about ~5mb big.
this command always returns '1' even if the changes are not reflected in the database(sometime it works, sometime it doesnt):
cmd.ExecuteNonQuery();
Thanks in advance!
I don't know if the mysql provider uses autocommit? If not then you have to call commit on the Transaction object you can get with BeginTransaction on the connection object.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.parameters.aspx
The Microsoft .NET Framework Data Provider for SQL Server does not support the question mark (?) placeholder for passing parameters to a SQL Statement or a stored procedure called by a command of CommandType.Text. In this case, named parameters must be used.
For example:
SELECT * FROM Customers WHERE CustomerID = #CustomerID
Edit:
Just noticed this was MySQL, and while i can't find anything simliar about it quickly, i would suggest you use named parameters anyways
I had this problem and it was related to autocommit.
Problem: earlier in the app lifespan autocommit was set to 0 by another process in the app, and failed. The connection with autocommit turned off is then reused by the connection pool.
That will lead to this type of error at unpredictable times.

getting {"could not execute batch command.[SQL: SQL not available]"} error from NHibernate

I took a look at other related posts but couldn't find any solution.
Sometimes on sesstion.Flush() I get the following error:
{"could not execute batch command.[SQL: SQL not available]"}
and the Inner Exception :
{"The UPDATE statement conflicted with the FOREIGN KEY constraint FK1377052553ABF955. The conflict occurred in database ProcessDebug, table dbo.Adjustment, column 'AdjustmentId'.The statement has been terminated."}
a piece of Process class mapping :
References(p => p.CurrentAdjustment)
;
References(p => p.DefaultAdjustment)
;
HasMany(p => p.Adjustments)
.Cascade.AllDeleteOrphan()
.Inverse()
;
All these properties above are of type of Adjustment.
As long as I get this error once in a while I couldn't track it down. For an entity it might happen now, but not next time in a same piece of code....
Any idea what might cause the problem?
I'm using NH 3.2 and FluentNhibernate
Thanks in advance
In my situation, it was "NULL" in one of the databese columns. Check your database data.
FOREIGN KEY -> this means, that you propably have null i column, that is use for "join".
p.s. Take SQL Profiler and check the SQL generated by nHibernate.
You need to look at the sql that is actually trying to execute.
It appears as though you are trying to update the primary key ("AdjustmentId") to something that does not exist. Hence the foreign key violation.
it seems about you database, not your nHibernate codes, check the SQL in log file, and try to exec it
To find the actual cause, you'll need to see the SQL that is being generated by nHibernate. You can either use nHibernate log or nHibernate profiler to get these SQL. Few of the common issues related to the above error message, include:
String or binary data would be truncated. An example of this issue is whenever you provide a string value that is larger than the defined varchar/nvarchar field size in database.
Expected primary or foreign key value is null
may be its not NHibernate problem!
please check in database which column is Not Null/Null. For this,I set null those columns.
You can do anything! set value when insert or set null on those column on table.
In my case I'm adding a data with column whose type is DateTime,
I insert 2100/2/2 get this error, but when insert more reasonable time 2001/2/2 get success,
so maybe the problem is in your data, and should follow some rule in database.

Categories