my sql table column accepting "0" as value - c#

I have two tables one is members table with columns member id , member first name, member last name. I have another table guest passes with columns guest pass id and member id and issue date .
I have a list view that will displays guest passes details (I.e) like member name and issue date and I have two text boxes those are for entering member name and issue date .
member name text box is auto complete text box that working fine....
but the problem is when I am entering the name that is not in member table at this time it will accept and displays a blank field in list view in member name column and member id is stored as "0" in guest pass table ......
I don't want to display the member name empty blank and I don t want to store "0" in guest pass table
and this is the insert statement
sql2 = #"INSERT INTO guestpasses(member_Id,guestPass_IssueDate)";
sql2 += " VALUES(";
sql2 += "'" + tbCGuestPassesMemberId.Text + "'";
sql2 += ",'" + tbIssueDate.Text + "'";
guestpassmemberId = memberid
is there any validation that need to be done
and this is the auto complete text box statement
sql = #"SELECT member_Id FROM members WHERE concat(member_Firstname,'',member_Lastname) ='" + tbMemberName.Text+"'";
dt = GetData(sql, mf);
if (dt != null)
{
if (dt.Rows.Count > 0)
{
tbCGuestPassesMemberId.Text = Convert.ToInt32(dt.Rows[0] ["member_Id"]).ToString();
}
}
can any one help me on this ...
is there any type of validation with sql query
pls help me .....

You can validate the values before passing them to the INSERT. Additionally you can also set a constraint to validate versus a regular expression in SQL.
SQL constraints
To validate before inserting you should have something like this:
private void validateData(Long memberId) {
//Pseudo code Depends on how you are connecting to your database...
SQLQuery query = getQuery("existsMemberId");
query.setParameter("memberId");
executeQuery(query);
// If the query returns something then the reference exists and it is ok to proceed
}
In the file you are storing your queries...
#existsMemberId
select 1
from members mem
where mem.id = :id <-- parameter
Additionally you should make foreign key constraint between members and guest passes with ID as the foreign key:
ALTER TABLE GuestPasses
ADD CONSTRAINT fk_memberId
FOREIGN KEY (id)
REFERENCES Members(id)

Related

C# Error Message:Cannot insert the value NULL into column 'Id

I develop a program who save a picture. But I get this error message:
Cannot insert the value NULL into column 'Id'
private void savepicture()
{
if(pictureBox1.Image != null)
{
MemoryStream ms = new MemoryStream();
pictureBox1.Image.Save(ms, pictureBox1.Image.RawFormat);
byte[] a = ms.GetBuffer();
ms.Close();
cm.Parameters.Clear();
cm.Parameters.AddWithValue("#picture", a);
cm.CommandText = "insert into Bild (FileName,Datei) values ('" + label1.Text.ToString() + "',#picture )";
sc.Open();
cm.ExecuteNonQuery(); // i get here the error message
sc.Close();
label1.Text = "";
pictureBox1.Image = null;
MessageBox.Show("Bild wurde gespeichert !");
}
}
Before anything you should check for a structure of your table Bild,
there you probably have a column called Id which is constraint and can not be a null.
And by reading your code I can not see on next line that you are supplying 'Id' to your sql:
cm.CommandText = "insert into Bild (FileName,Datei) values ('" + label1.Text.ToString() + "',#picture )";
What you should do here is next:
Send id from your code to a sql (create variable and include it in insert command) depending of your column type (int, guid or whatever, so if you are using int you should incremet your variable which will hold value for next 'Id' in your database, or if it is Guid you should create new Guid for every new row using Guid.NewGuid method )
Edit id column on Sql and apply AUTO_INCREMENT keyword to perform an auto-increment feature, example :
Alter TABLE Bild(
id int NOT NULL AUTO_INCREMENT,
rest of columns
);
Or you might apply next steps in case you are using Microsoft SQL and I guess you do because I can see you are using SqlCommand.CommandText Property in your C# code.
Presumably you are in the design of the table. If not: right click the
table name - "Design". Click the required column. In "Column
properties" (at the bottom), scroll to the "Identity Specification"
section, expand it, then toggle "(Is Identity)" to "Yes".
I cannot add comments so i will answer here.
If your Id is the primary key, you either insert it yourself or use the identity option (auto increment):
add the identity option to the key from ssms. If you want to do it by query follow the answer given here https://dba.stackexchange.com/questions/128433/add-autoincrement-to-existing-pk
in your insert statement do insert into Bild (Id,FileName,Datei) values ([your id], 'val1', 'val2').
Note: You have to specify the Id you want to insert if your primary key does not have an way of doing it itself (auto increment)

Insert query where table name is textbox text

I have a problem in button1 click event of inserting data into a table which table name be determined by whatever text is in textbox1
Should mean something like that:
tablename = textbox1.text;
sql = "INSERT INTO tablename ([itemserial], [itemname], [itemcount],[itemimage]) VALUES (#itemserial, #itemname, #itemcount, #itemimage)";
Having a textbox containing the name of your table is challenging because you should add extra care in handling this value. You should implement some kind of checking on this textbox value. A possible solution is to check against your database schema if the table typed by your user really exists.
You don't tell us which database system are you using so I will show an example using Sql Server
string tableName = textbox1.text;
using(SqlConnection cnn = new SqlConnection(... connectionstring...))
{
cnn.Open();
DataTable dt = cnn.GetSchema("TABLES");
DataRow[] rows = dt.Select("TABLE_NAME = '" + tableName + "'");
if(rows.Length > 0)
{
// Now you are sure to have a valid table in your textbox
// and could use the input value without risking an Sql Injection
string sql = "INSERT INTO [" + tableName + "] ([itemserial]," +
"[itemname],[itemcount],[itemimage]) " +
"VALUES(#itemserial,#itemname,#itemcount,#itemimage)";
.... the remainder of your code that use the query above....
}
else
MessageBox.Show("Please enter a valid name for your table");
Extending this approach you could change your TextBox to a ComboBox with ComboBoxStyle set to DropDownList (to block typing) and fill the ComboBox with the names returned by the GetSchema call above....
tablename = textbox1.text;
sql = string.Format("INSERT INTO {0} ([itemserial],[itemname],[itemcount],[itemimage])VALUES(#itemserial,#itemname,#itemcount,#itemimage)", tablename);
Although I would strongly recommend against this as it allows people to enter whatever they want into that textbox. Something like:
Robert; DROP TABLE Students;--
Which is discussed in more detail here:
How does the SQL injection from the "Bobby Tables" XKCD comic work?
Change your query like this
sql = "INSERT INTO "+tablename+" ([itemserial],[itemname],[itemcount],[itemimage]) VALUES (#itemserial,#itemname,#itemcount,#itemimage)";

Disable dapper.rainbow from using ID while inserting

I am using dapper.rainbow for inserting a record into MSSQL db. Following is my code
int? id = db.RoomTypes.Insert(roomType)
When i run my app, i am getting the below exception.
Cannot insert explicit value for identity column in table 'RoomTypes'
when IDENTITY_INSERT is set to OFF.
I think that dapper.rainbow is using the value (default value for int) for my Identity Column during the insert. This is what causing this exception. My identity column for the table RoomTypes is auto incremented and it is also the primary key of my table.
Now, how do i stop the dapper.rainbow from using the ID column during insert.
Looking at the Dapper.Rainbow.Insert method, the method is "dumb" to the type passed in as the data parameter:
public virtual int? Insert(dynamic data)
{
var o = (object)data;
List<string> paramNames = GetParamNames(o);
string cols = string.Join(",", paramNames);
string cols_params = string.Join(",", paramNames.Select(p => "#" + p));
var sql = "set nocount on insert " + TableName + " (" + cols + ") values (" + cols_params + ") select cast(scope_identity() as int)";
return database.Query<int?>(sql, o).Single();
}
In other words, if you include the ID as a property in the parameter, then Dapper will try to insert that value into the database. And as you've seen, if you have IDENTITY_INSERT set to Off, then the insert will fail.
This means you'll need to create a new type that doesn't include your ID property to pass into the method. A few of ideas come to mind:
Create a base class without the ID for RoomTypes and then just pass in the base class to the Insert method.
Create a dynamic parameter and pass that to the Insert method with only the properties you want to insert into the database.
Override the Insert method and remove the ID parameter before sending to the Dapper

Unique number identifier generation

I have to create logic for generation unique number identifier for records in database. id, generated in database is a separate column.
At this moment, when user calls "create record" action, I save new record, get its database id, generate record number using this id, then put it to the edit form.
Using this way means that all entity fields should be nullable to save record to database.
I don't like this way. I know that should be better way.
Is there a better practice to generate unique number identifier? What is possibility of generating non-unique random numbers?
Thank you
The pattern that you're using, of saving an empty record simply to get the ID, is not a good one.
The standard approach, and the one that I'd recommend, is for Create Record to simply display an empty form (the ID at this point will typically be 0). The user fills in the form and the data is only committed to the database when the user clicks Save. The ID should be an IDENTITY column.
A problem with your approach is that if users do not complete the form, you end up with lots of incomplete records in your database. And, of course, it makes it much more difficult to handle data validation and integrity.
An alternative approach, if you really must display the ID to the user, is to have a separate table containing a row with a "Next Record ID" column. This column can be incremented and returned as an atomic operation and used to populate the ID of your new record. You still don't create the real record, just increment this "Next Record ID" in your Create Record action. Using this approach, you can use the same approach for multiple entities by having separate rows for each in this "Record IDs" table. Bear in mind that if the user does not ultimately save the record to the database, an ID will still have been 'used up'. The numbers will still be unique and will be chronological but won't necessarily be contiguous.
I don't get it, but, if you are using the uniqueidentifier data type in your database, that translates to Guid in C#, so you can do:
public Guid CreateRecord(MyObject model) {
Guid newId = Guid.NewGuid();
MyTable tbl = new MyTable();
tbl.guid = newId;
// ... other columns
db.MyTable.AddObject(tbl);
db.SaveChanges();
return newId;
}
though what I normally do, is having the PrimaryKey as int and add a uniqueidentifier field named guid (that I use it publically instead the column_id) and remember to index that column.
Code for Table..
CREATE TABLE TblTransactions(
TId varchar(8),
TName varchar(50)
)
C# Code Behind…
protected void Page_Load(object sender, EventArgs e)
{
string id = GenerateId("TblTransactions", "TId", 8, "TRN");
// insert the id along with data in the table
Response.Write(id);
}
public string GenerateId(string TableName, string ColumnName, int ColumnLength, string Prefix)
{
SqlConnection con = new SqlConnection("server=.;integrated security=true;database=EBissCard");
string Query, Id;
int PrefixLength, PadLength;
PrefixLength = Convert.ToInt32(Prefix.Length);
PadLength = ColumnLength - PrefixLength;
Query = "SELECT '" + Prefix + "' + REPLACE(STR(MAX(CAST(SUBSTRING(" + ColumnName + "," + Convert.ToString(PrefixLength + 1) + "," + PadLength + ") AS INTEGER))+1," + PadLength + "),' ',0) FROM " + TableName;
SqlCommand com = new SqlCommand(Query, con);
con.Open();
if (com.ExecuteScalar().ToString() == "")
{
Id = Prefix;
for (int i = 1; i <= PadLength - 1; i++)
{
Id += "0";
}
Id += "1";
}
else
{
Id = Convert.ToString(com.ExecuteScalar());
}
con.Close();
return Id;
}
An idea to generate a unique number for a record is to use the time() in milliseconds (since a reference point of time, say, 01/01/2010).
However, if there are 2 records that are simultaneously getting updated, this may cause an issue. To solve this problem, if each of the user can be assigned a number (when creating the userID), a combination (concatenation) of that "user number" and time in milliseconds will give you the unique number you need.
Try the Random class from .net itself.

use serial field per user in the entity framework

I have an entity with code field. For each user that uses this entity, each entity the user insert must have code. So I wrote code that do the following logic:
1. if the user set the code field - then use his code.
2. if the user doesn't set the code field - read from the db the next serial code (starting from 1, searching the next serial code that doesn't already exists) and use this code.
The probelm is scenario like this:
Assuming the user have the ability to add two entities in single mouse click.
Assuming the next serial code should be "5".
In the first entity the user set code=5 and in the second entity the user doesn't set the code.
Because I am using the entity framework and there is one commit/save changes at the end of the logic, I Insert the first entity (the one with code=5) and for the second entity, searching the db for the next next serial code that doesn't already exists. The next serial code that doesn't already exists in the database is "5". So I set the second entity the code "5".
Eventually I came up with two entities with code=5 which is wrong.
I thought of ways to solve it.
One way is to do SaveChanges right after storing the first entity but this might make many calls to the db, and I am not sure for this solution.
Another way is to search in the DB and in the attached objects but I really don't know how to do it.
Does anyone has any better idea?
You can use an IDENTITY column to allow SQL Server to auto-populate it when the user doesn't specify one, and when you have one that they do specify you just put it in your INSERT/UPDATE query along with the other fields. It will save your value instead of creating a new one. You do need to check and make sure that the ID hasn't already been used before doing that if you have a unique constraint on that field or if you don't want to allow duplicates when the user specifies a value.
The following example uses a table called MyTable with 3 columns (ID int IDENTITY, FIRST_NAME varchar, LAST_NAME varchar). I would recommend using parameters instead of passing the values in the sql string as I did below since this was just an example and it was faster to put together that way.
String sSQL = "";
String sFields = "";
String sValues = "";
String sCode = "";
// sCode = ... (get user entered code)
String sFirstName = "John";
String sLastName = "Doe";
if (sCode != "")
{ //Add the user specified value and field for the identity column to the SQL
sFields = "ID, ";
sValues = sCode + ", ";
}
sFields += "FIRST_NAME, LAST_NAME";
sValues += "'" + sFirstName.Replace("'","''") + "', '" + sLastName.Replace("'","''") + "'";
sSQL = "INSERT INTO MyTable (" + sFields + ") VALUES (" + sValues + ")"
//execute the sql statement

Categories

Resources