My project in C# Winforms 2010 and use SQL Server express and Linq-to-SQL. My project get me exception:
The INSERT statement conflicted with the CHECK constraint "CK_BarCode_Num". The conflict occurred in database "Parking", table "dbo.TBL_Cards", column 'BarCode_Num'
and when I ran this query:
SELECT name, definition
FROM sys.check_constraints
WHERE name = 'CK_BarCode_Num'"
the output shows the definition of:
Name: CK_BarCode_Num
Definition: (datalength([BarCode_Num])=(13))"
but in TBL_Cards in database, type of BarCode_Num is varchar(100) and in code behind, I declare int for type of BarCode_Num.
I don't know where is set datalength([BarCode_Num])=(13)?
The check constraint is saying that whatever you insert into Barcode_Num has to be exactly 13 characters long.
If you're trying to insert something that isn't 13 characters long, I'd recommend you consult the documentation for your database (or talk to whoever set it up) to understand why this constraint has been applied.
We'll not be able to answer that for you, and I wouldn't recommend altering the check constraint without understanding why it exists in the first place.
DATALENGTH
Returns the number of bytes used to represent any expression.
For varchar, the number of bytes used corresponds 1-1 with the number of characters. For nvarchar you would need to divide by 2.
The data type is separate from any check constraints you have defined. You can modify the check constraint following these instructions: http://msdn.microsoft.com/en-us/library/ms191273.aspx
Otherwise, you can perform the data validation in your own code - Linq to SQL won't enforce it on the entity, but will throw a SqlException when you attempt to perform an insert that violates the constraint.
Related
I'm using the EntityFramework BulkInsert extension to insert large datasets into my database. However, there is an AFTER INSERT trigger on the table that I'm inserting data into that doesn't seem to be firing. Is this a limitation of the extension or is there a way to ensure that the trigger fires when the operation completes?
It turns out I just wasn't looking hard enough. There are some overloads for the main BulkInsert method that are not listed anywhere in the documentation and I could not find them through any Google searches, but one of the overloads allow for flags. One of the flags is SqlBulkCopyOptions.FireTriggers.
It is used like: context.BulkInsert(values, SqlBulkCopyOptions.FireTriggers). Using this method, each row is processed individually by the trigger, and everything works as it should.
EDIT: Answer comment
can you explain what the CheckConstraint will do?
A constraint is when you add some checks such as the value must be between 10 and 50 to be valid and inserted.
So if you don't check constraint, a value of 5 will be inserted without a problem even if out of range. If you check constraint, an error will be throw:
The INSERT statement conflicted with the CHECK constraint "CHK_ColumnWithConstraint". The conflict occurred in database "db_2560", table "dbo.Customers", column 'ColumnWithConstraint'.
The statement has been terminated.
Here is an online example: https://dotnetfiddle.net/AMgTYQ
That's why I recommend SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints
If the table have a trigger, you probably when to fire them. If a column has a constraint, you probably want the operation to throw an error if the value is not valid with the check.
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.
I am bulk inserting a long list of object.
than i execute a commit.
It fails sometimes with the error (C#)
"The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_MyFK". The conflict occurred in database "DCDCommunity", table
"MySchema.MyTable", column 'Id'.\r\nThe statement has been terminated."}
System.Exception {System.Data.SqlClient.SqlException}
Now, do I have to write a program that iterates on my data files to find the value or can I get it in the exception?
I can't answer "why?" but I can offer a suggestion - do some pre-checks to your data before doing a bulk insert to make sure foreign keys are valid, and whatever other data issues you might regularly face - like checking string lengths to avoid the "string or binary data would be truncated" error as mentioned in a comment.
Is there a way for SQL to enforce unique column values, that are not a primary key to another table?
For instance, say I have TblDog which has the fields:
DogId - Primary Key
DogTag - Integer
DogNumber - varchar
The DogTag and DogNumber fields must be unique, but are not linked to any sort of table.
The only way I can think of involves pulling any records that match the DogTag and pulling any records that match the DogNumber before creating or editing (excluding the current record being updated.) This is two calls to the database before even creating/editing the record.
My question is: is there a way to set SQL to enforce these values to be unique, without setting them as a key, or in Entity Frameworks (without excessive calls to the DB)?
I understand that I could group the two calls in one, but I need to be able to inform the user exactly which field has been duplicated (or both).
Edit: The database is SQL Server 2008 R2.
As MilkywayJoe suggests, use unique key constraints in the SQL database. These are checked during inserts + Updates.
ALTER TABLE TblDog ADD CONSTRAINT U_DogTag UNIQUE(DogTag)
AND
ALTER TABLE TblDog ADD CONSTRAINT U_DogNumber UNIQUE(DogNumber)
I'd suggest setting unique constraints/indexes to prevent duplicate entries.
ALTER TABLE TblDog ADD CONSTRAINT U_DogTag UNIQUE(DogTag)
CREATE UNIQUE INDEX idxUniqueDog
ON TblDog (DogTag, DogNUmber)
It doesn't appear as though Entity Framework supports it (yet), but was on the cards. Looks like you are going to need to do this directly in the database using Unique Constraints as mentioned in the comments.
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.