I have a table with these columns:
PersonID AutoNumber PrimaryKey
TCKimlikNo Number
PersonName Text
PersonSurname Text
Address Text
Birthdate Text
CategoryID Number
When im trying to insert value from c# I am using this query:
INSERT INTO Person(TCKimlikNo, PersonName, PersonSurname, Adress, BirthDate, CategoryID)
VALUES(#tcKimlikNo, #personName, #personSurname, #adress, #birthDate, #categoryId)
But it says:
"Microsoft Access set 1
field to Null due to type conversion
failure, and it didn't add 0 record(s)
to the table due to key violations, 0
record(s) due to lock violations, and
0 record(s) due to validation rule
violations."
I think the error occuring because of that autonumber column. Access trying to insert null value to that, but field wont let it. In SQL this query works perfectly. But Access is just annoying.
The NULL value is because of a type conversion issue. Most likely you are passing data into one of your fields that cannot be converted by Access into the data type that it is expecting. I would guess that you are passing in a value to CategoryID that is not converting to a proper number. This could also be true of the TCKimlinkNo field. I believe if the string field is too short for the passed-in values, it will just truncate them so I doubt this is the issue.
Also, don't forget to check the size of your number fields. Is the number you are entering larger than the number allowed? Are you sending decimal data when it is expecting a whole number?
The autonumber won't be a problem unless you are trying to write to it (which you don't appear to be doing.
Related
I have a table Drivers with columns Id, Name, Status. In C# I have an enum for driver status
public enum DriverStatus
{
Online = 0,
Offline = 1,
Busy = 2,
SoonFree = 3
}
Currently in the database, I use a varchar data type for the Status column and this means I have records like:
1 John Online
2 Elsy Offline
This seams to be bad and I think this need to be changed to status column type tinyint because:
T-SQL Tinyint is only one byte size with range 0-255.
Now it is not possible to normally sort by status column because it is varchar so it sorts in alphabetical order not in enum priorities.
If I rename DriverStatus enum value name I also need to update database to be consistent.
Then I asked others why we use varchar for enum columns the only reason was that it is easier to debug as you see text not number like 0 or 3. Is where any really good reasons to have strings for enums in the database?
It is absolutely better to use a Lookup Table for enum values.
Advantages:
Usually less room in the database is used.
Renaming the display value is very easy.
Globalization is possible.
It is easy to retire values that are no longer used.
My lookup tables always contain three fields: [the ID/Primary Key], Name, and Enabled
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.
If i do a query like this
SELECT * from Foo where Bar = '42'
and Bar is a int column. Will that string value be optimized to 42 in the db engine? Will it have some kind of impact if i leave it as it is instead of changing it to:
Select * from Foo where Bar = 42
This is done on a SQL Compact database if that makes a difference.
I know its not the correct way to do it but it's a big pain going though all code looking at every query and DB schema to see if the column is a int type or not.
SQL Server automatically convert it to INT that because INT has higher precedence than VARCHAR.
You should also be aware of the impact that implicit conversions can
have on a query’s performance. To demonstrate what I mean, I’ve created and populated the following table in the AdventureWorks2008 database:
USE AdventureWorks2008;
IF OBJECT_ID ('ProductInfo', 'U') IS NOT NULL
DROP TABLE ProductInfo;
CREATE TABLE ProductInfo
(
ProductID NVARCHAR(10) NOT NULL PRIMARY KEY,
ProductName NVARCHAR(50) NOT NULL
);
INSERT INTO ProductInfo
SELECT ProductID, Name
FROM Production.Product;
As you can see, the table includes a primary key configured with the
NVARCHAR data type. Because the ProductID column is the primary key,
it will automatically be configured with a clustered index. Next, I
set the statistics IO to on so I can view information about disk
activity:
SET STATISTICS IO ON;
Then I run the following SELECT statement to retrieve product
information for product 350:
SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = 350;
Because statistics IO is turned on, my results include the following
information:
Table 'ProductInfo'. Scan count 1, logical reads 6, physical reads 0,
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob
read-ahead reads 0.
Two important items to notice is that the query performed a scan and
that it took six logical reads to retrieve the data. Because my WHERE
clause specified a value in the primary key column as part of the
search condition, I would have expected an index seek to be performed,
rather than I scan. As the figure below confirms, the database engine performed a scan, rather than a seek. Figure below shows the details of that scan (accessed by hovering the mouse over the scan icon).
Notice that in the Predicate section, the CONVERT_IMPLICIT function is
being used to convert the values in the ProductID column in order to
compare them to the value of 350 (represented by #1) I passed into the
WHERE clause. The reason that the data is being implicitly converted
is because I passed the 350 in as an integer value, not a string
value, so SQL Server is converting all the ProductID values to
integers in order to perform the comparisons.
Because there are relatively few rows in the ProductInfo table,
performance is not much of a consideration in this instance. But if
your table contains millions of rows, you’re talking about a serious
hit on performance. The way to get around this, of course, is to pass
in the 350 argument as a string, as I’ve done in the following
example:
SELECT ProductID, ProductName
FROM ProductInfo
WHERE ProductID = '350';
Once again, the statement returns the product information and the statistics IO data, as shown in the following results:
Now the index is being properly used to locate the record. And if you
refer to Figure below, you’ll see that the values in the ProductID
column are no longer being implicitly converted before being compared
to the 350 specified in the search condition.
As this example demonstrates, you need to be aware of how performance
can be affected by implicit conversions, just like you need to be
aware of any types of implicit conversions being conducted by the
database engine. For that reason, you’ll often want to explicitly
convert your data so you can control the impact of that conversion.
You can read more about Data Conversion in SQL Server.
If you look into the MSDN chart which tells about the implicit conversion you will find that string is implicitly converted into int.
both should work in your case but the norme is to use quote anyway.
cuz if this work.
Select * from Foo where Bar = 42
this not
Select * from Foo where Bar = %42%
and this will
SELECT * from Foo where Bar = '%42%'
ps: you should anyway look at entity framework and linq query it make it simple...
If i am not mistaken, the SQL Server will read it as INT if the string will only contains number (numeric) and you're comparing it to the INTEGER column datatype, but if the string is is alphanumeric , then that is the time you will encounter an error or have an unexpected result.
My suggestion is , in WHERE clause, if you are comparing integer, do not put single quote. that is the best practice to avoid error and unexpected result.
You should use always parameters when executing sql by code, to avoid security lacks (EJ: Sql injection).
I have a row that contains a field defined as varchar(MAX). I'm confused about the limit of the field: in some places, I read that varchar(MAX) has a size limit of 8K and in other places it seems that the limit is 2GB.
I have a string that I want to save to a database; it's about 220K. I'm using linq-to-sql and when the write query submits to the database, the row gets written without any exceptions generated. However, when I open the database table in SSMS, the cell that should contain the long string is empty. Why is that and how do I take advantage of the 2GB limit that I read about?
This is the property in the linq-to-sql model:
All MAX datatypes--VARCHAR(MAX), NVARCHAR(MAX), and VARBINARY(MAX)--have a limit of 2 GB. There is nothing special you need to do. Without specifying MAX, the limit for VARCHAR and VARBINARY are 8000 and the limit for NVARCHAR is 4000 (due to NVARCHAR being double-byte). If you are not seeing any data come in at all, then something else is going on.
Are you sure that the column is even in the INSERT statement? If you submit test data of only 20 characters, does that get written? If you want to see what SQL is actually submitted by Linq, try running SQL Profiler and look at the SQL Statement: Statement Ended event, I believe.
Also, when you say that the "long string is empty", do you mean an actual empty string or do you mean NULL? If it is not NULL, you can also wrap the field in a LEN() function to see if there are blanks for returns at the beginning that push any non-whitespace characters out of view. Meaning, SELECT LEN(stringField), * FROM Table. Another thing to try is to use "Results to Text" instead of "Results to Grid" (this is a Query option).
EDIT:
Seeing that the field is marked as NOT NULL, are you sure that you are setting the ClientFileJS property of your object correctly? Is it possible that the empty string is due to that property being initialized as string ClientFileJS = ""; and is never updated?
Consider a SQL Server table defined with a varchar(1) NULL field. It's being used to store a gender character. Some rows have data, some not: either null or blank. Granted the blanks SHOULD be nulls, but consider that blank is a valid value here. I'd much prefer the value to be null.
ID Gender
1 'M'
4 'M'
3 ''
4 'F'
An exception is raised when running a Linq To Sql query where the value of someID is 3.
var emp = (from e in db.Employees
where e.ID == someID
select e);
Exception:
String must be exactly one character long.
Question: What is the cause of this exception? What can be done to prevent or eliminate this problem?
Check the Employee type that was created for you by the LINQ to SQL designer. Most likely the type for the Gender property is System.Char (which is the type that the LINQ to SQL designer uses for varchar(1)) and should be changed to a System.String to properly match your database schema.
The fact that the LINQ to SQL designer interprets a varchar(1) as a System.Char is foolish considering that this is valid T-SQL:
declare #foo varchar(1);
set #foo = '';
and this is invalid C#:
Char foo = '';
Since the type of the property that was generated is too restrictive you need to change it to be a System.String.
Note: You may want to consider adding some validation inside the setter of the property to throw an exception if the length of the string is greater than one.
Is it possible that the blank data like '' doesn't meet the current constraints of the table? E.g. perhaps the table doesn't permit empty strings (even though there is one in there).
Then, maybe LINQ is applying those constraints for you, or expecting those constraints to be met and complaining that they are not.
If this is what is going on, you might change the constraints/design of the table to allow blank values, or just update all the blank values to NULL (assuming NULLs are allowed)
This problem also occurs when Linq To SQL Designer tries to auto generate a results class, for holding stored procedure results. Copy the auto generated class into your own new class file (use same name) and make changes there. Each time you update your DataContext it will just be a case of deleting the auto generated class. Not an ideal solution but a workaround for 2008.