I am trying to make an insert to an MySql database using a three layer solution (or what it might be called).
I have done this may times with an MS-sql database and it has worked very well.
But now when I am trying to make an insert I get the the ID can't be null.
I thought the database took care of that.
If I write an insert directly in the code and use the MySqlCommand and executeNonQuery it works great.
Is it not possible to use BLL and DAL with MySql?
Error message:
System.Data.NoNullAllowedException: Column 'GiftID' does not allow nulls. at System.Data.DataColumn.CheckNullable(DataRow row) at System.Data.DataColumn.CheckColumnConstraint(DataRow row, DataRowAction action) at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent) at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Int32 position, Boolean fireEvent, Exception& deferredException) at System.Data.DataTable.InsertRow(DataRow row, Int32 proposedID, Int32 pos, Boolean fireEvent) at System.Data.DataRowCollection.Add(DataRow row) at PayEx.payexusersDataTable.AddpayexusersRow(payexusersRow row) in c:\Users\IT\AppData\Local\Temp\Temporary ASP.NET Files\payex\45bd406a\10c84208\App_Code.cyqhjqo7.1.cs:line 444 at PayExBLL.AddPayExUser(String Firstname, String Lastname, String Company, String Address, String Zip, String City, String Phone, String Email, Byte ContactMe, UInt32 Amount, UInt32 TransactionNumber, Byte Anonymous, String Currency) in c:\Users\IT\Documents\Visual Studio 2008\WebSites\payex\App_Code\BLL\PayExBLL.cs:line 66 at _Default.btn_next3_Click(Object sender, EventArgs e) in c:\Users\IT\Documents\Visual Studio 2008\WebSites\payex\Default.aspx.cs:line 191
My code:
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)]
public bool AddPayExUser(string Firstname, string Lastname, string Company, string Address, string Zip, string City, string Phone, string Email, byte ContactMe, uint Amount, uint TransactionNumber, byte Anonymous, string Currency)
{
PayEx.payexusersDataTable puTable = new PayEx.payexusersDataTable();
PayEx.payexusersRow puRow = puTable.NewpayexusersRow();
puRow.Firstname = Firstname;
puRow.Lastname = Lastname;
puRow.Company = Company;
puRow.Address = Address;
puRow.Zip = Zip;
puRow.City = City;
puRow.Phone = Phone;
puRow.Email = Email;
puRow.ContactMe = ContactMe;
puRow.Amount = Amount;
puRow.TransactionNumber = TransactionNumber;
puRow.Anonymous = Anonymous;
puRow.Currency = Currency;
puTable.AddpayexusersRow(puRow);
int rowsAffected = Adapter.Update(puTable);
return rowsAffected == 1;
}
System.Data.NoNullAllowedException: Column 'GiftID' does not allow nulls. at
From the looks of your code, you're forgetting to pass in a GiftID parameter to your function but it's expected (and can't be null) in your table row.
Hence the exception. Either set it in your code above, or define a default value on it in your MySQL database.
EDIT: This comment assumes you're inserting into a table for which GiftId is the primary key, which seems unlikely. If so, Eoin Campbell's answer makes more sense!
Check if GiftId is an AUTO_INCREMENT column; that's MySQL's equivalent of identity.
You can recreate the column as identity like:
ALTER TABLE Gifts
DROP COLUMN GiftId;
ALTER TABLE items
ADD COLUMN GiftId INT NOT NULL AUTO_INCREMENT FIRST;
Related
This is my C# code, and I get this error
An explicit value for the identity column in table 'tblImages' can only be specified when a column list is used and IDENTITY_INSERT is ON.
public partial class _Default : System.Web.UI.Page
{
// string strconn= ConfigurationManager.ConnectionStrings["con"].ConnectionString;
SqlConnection conn=new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\Final_Year_Project\ProjectFiles\ComSysForDeafAndDumb\App_Data\Database.mdf;Integrated Security=True");
static string query="";
static int myID = 989;
static string imgName;
static string imgSize;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblMessage.Visible = false;
hyperlink.Visible = false;
}
}
protected void btnUpload_Click(object sender, EventArgs e)
{
string b = "";
FileUpload1.SaveAs(Request.PhysicalApplicationPath +"./images/"+ FileUpload1.FileName.ToString());
b="~/images/"+ FileUpload1.FileName.ToString();
query = "insert into tblImages values ("+myID+",'"+imgName+"','"+imgSize+"','"+b+"','"+txtdes.Value+"')";
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Response.Write("successful");
imgUpload.ImageUrl = b;
}
}
When you do this:
insert into tblImages values (123, 'some value', 'another value')
The database will map the supplied values directly to the column list in the table. But one of your columns does not allow explicitly inserted values. Specifically the identity column, which is usually the first column in the table and usually called something like ID.
Instead of trying to insert into all columns, explicitly insert into the columns you want. We don't know the structure of your table, but as an example the INSERT command would look something like this:
insert into tblImages (ImageName, ImageSize) values ('some value', 'another value')
Where ImageName and ImageSize would be names of your columns. Expand this to include all of the columns into which you want to insert values, and to include all of the values you're trying to insert for that record. Basically, explicitly specify which columns you want to write to and don't try to write to the identity column.
Also, and this is important, your code is wide open to SQL injection. This question has some good explanations and examples of how to address that. Basically you should always treat user input as values and not as executable code in your SQL commands.
Created a website login system but when I run it it keeps coming up with this error to the particular bit of coding below. Can someone PLEASE help me with this Error message on this particular code:
System.Data.SqlClient.SqlException: Incorrect syntax near the keyword
'user'.
Code:
public static User LoginUser(string login, string password)
{
//Check if user exists
string query = string.Format("SELECT COUNT(*) FROM TeesDB.dbo.user WHERE name = '{0}'",
login);
command.CommandText = query;
try
{
conn.Open();
int amountOfUsers = (int) command.ExecuteScalar();
if(amountOfUsers == 1)
{
//User exists, check if the password match
query = string.Format("SELECT password FROM users WHERE name = '{0}", login);
command.CommandText = query;
string dbPassword = command.ExecuteScalar().ToString();
if (dbPassword == password)
{
//password match. Login and password data are known to us.
//retrieve further user data from the database
query = string.Format("SELECT email, user_type FROM users WHERE name =
'{0}'", login);
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
User user = null;
while (reader.Read())
{
string email = reader.GetString(0);
string type = reader.GetString(1);
user = new User(login, password, email, type);
}
return user;
}
else
{
//passwords do not match
return null;
}
}
else
{
//user exists
return null;
}
}
finally
{
conn.Close();
}
}
}
}
That happens because USER is a reserved keyword. To refer to it in your queries you need to encapsulate the word between square brackets
string query = string.Format("SELECT COUNT(*) FROM [user] WHERE name = .....
but at this point, why in subsequent queries you use the name users? It is just a typo in the first query or in the next?
However, you should also keep in mind that string formatting your queries in that way is very bad.
You are at risk of Sql Injections and, if a single quote appears in your text values, the whole query will resul in an invalid syntax
As an example of a parameterized query to replace your query
string query = "SELECT COUNT(*) FROM [user] WHERE name = #name",
command.CommandText = query;
command.Parameters.AddWithValue("#name",login);
int amountOfUsers = (Convert.ToInt32(command.ExecuteScalar());
if(amountOfUsers > 0)
{
.....
}
Then the next problem is the password retrieved from the database and compared with the user input. Having this kind of code means the password is stored in clear text inside the database. A clear security risk. You should store passwords in an encrypted form. When you need to check the user credentials you apply the same crypting algorithm to the user input and checks against the password in the database.
You could do this in a single operation
string cryptPwd = EncryptPassword(password);
string query = "SELECT COUNT(*) FROM [user] WHERE name = #name and password = #cryptpwd",
....
i am trying to perform insert but getting this error:
[Exception: One or more errors occurred during processing of command.
ORA-00936: missing expression]
it works for select query.
table structure is as follow
database-oracle 10g
table name-investor_info
investor_id-number
first_name-varchar
lastname-varchar
age-number
location-varchar
contact_number-varchar
email-varchar
checked-number-number
public void insert_details(string fname,string lname, int age, string location, string contactnumber, string email)
{
int id = get_id()+1;
int check=0;
string query = "INSERT INTO INVESTOR_INFO (INVESTOR_ID,FIRST_NAME,LAST_NAME,AGE,LOCATION,CONTACT_NUMBER,EMAIL,CHECKED) VALUES (#val1,#val2,#val3,#val4,#val5,#val6,#val7,#val8);";
try
{
conn.Open();
OleDbCommand command1 = new OleDbCommand(query,conn);
command1.Parameters.AddWithValue("#val1", id);
command1.Parameters.AddWithValue("#val2", fname);
command1.Parameters.AddWithValue("#val3", lname);
command1.Parameters.AddWithValue("#val4", age);
command1.Parameters.AddWithValue("#val5", location);
command1.Parameters.AddWithValue("#val6", contactnumber);
command1.Parameters.AddWithValue("#val7", email);
command1.Parameters.AddWithValue("#val8", check);
command1.CommandType = CommandType.Text;
command1.ExecuteNonQuery();
// conn.Close();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
finally
{
conn.Close();
}
}//end of insert
Remove the semicolon in string QUERY
it should be
string query = "INSERT INTO INVESTOR_INFO (INVESTOR_ID,FIRST_NAME,LAST_NAME,AGE,LOCATION,CONTACT_NUMBER,EMAIL,CHECKED) VALUES (#val1,#val2,#val3,#val4,#val5,#val6,#val7,#val8)";
Remove semicolon from the string query and try like below,
string query = "INSERT INTO INVESTOR_INFO (INVESTOR_ID,FIRST_NAME,LAST_NAME,AGE,LOCATION,CONTACT_NUMBER,EMAIL,CHECKED) VALUES (#val1,#val2,#val3,#val4,#val5,#val6,#val7,#val8)";
Always specific the schema name with table name.(schemeName.tableName)
I have not worked on Oracle for a while, but have you tried replacing the # with a : for the parameters. Refer to the following artice:
http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oraclecommand.parameters.aspx
Okay I am a noob to parameterized queries. I understand why you should use them and all but I cannot find any resource that shows the correct way or at least one that shows the correct way that actually works.
So my question is about whether or not my code is right. It compiles and runs just fine but it returns absolutely nothing in the gridview.
protected void SearchButton_Click(object sender, EventArgs e)
{
string searchBoxValue = SearchBox.Text;
string columnNameValue = ColumnName.SelectedValue;
columnNameValue.ToLower();
SqlCommand searchCommand = new SqlCommand();
searchCommand.Connection = connection;
searchCommand.CommandText = "select firstname AS FirstName,lastname AS LastName, zipcode as ZipCode, phone AS Phone, email AS Email, cancersurvivor AS CancerSurvivor, ethnicity AS Ethnicity from registrants where #columnname = #searchterm";
SqlParameter columnParam = new SqlParameter();
columnParam.ParameterName = "#columnname";
columnParam.Value = columnNameValue;
SqlParameter searchBoxParam = new SqlParameter();
searchBoxParam.ParameterName = "#searchterm";
searchBoxParam.Value = searchBoxValue;
searchCommand.Parameters.Add(columnParam);
searchCommand.Parameters.Add(searchBoxParam);
UpdateTable(searchCommand);
}
The UpdateTable function takes in the an SqlCommand object and then uses a DataAdapter object to execute the command and fills a DataTable object then sets the gridview datasource to the datatable object and binds it.
Like I said before I am really looking for the proper way to do this? do I need a stored procedure in order to do this? I am confused by all this and why it is not working.
You cannot parameterise #columnname. This needs to be a literal in your query.
Your statement
select
/* .... */
from registrants where #columnname = #searchterm
will return all rows from registrants if the value of the parameters happens to be the same or no rows otherwise.
It will not look and see if you have a column of that name and see if #searchterm exists in it.
To do this in a safe way you would need to check that columnNameValue matches one of a whitelist of valid column names (as you must know the possible column names in that table) and concatenate it into your query. Do not concatenate unvalidated user input. as then you open yourself up to SQL injection.
So you might implement it something like
using System.Linq;
protected void SearchButton_Click(object sender, EventArgs e)
{
string columnNameValue = ColumnName.SelectedValue.ToLower();
var validColumnNames = new string[] { "firstname", "lastname", "zipcode" };
if (!validColumnNames.Contains(columnNameValue))
{
throw new Exception("Unexpected column name " + columnNameValue);
}
/* ... code omitted */
searchCommand.CommandText = "select firstname AS FirstName,lastname AS LastName, zipcode as ZipCode, phone AS Phone, email AS Email, cancersurvivor AS CancerSurvivor, ethnicity AS Ethnicity from registrants where " + columnNameValue + " = #searchterm";
/* ... code omitted */
}
The purpose of paramtrized command are to prevent sql injection. You cannot parametrize the name of the column, sql will take it as a string.
protected void SearchButton_Click(object sender, EventArgs e)
{
string searchBoxValue = SearchBox.Text;
string columnNameValue = ColumnName.SelectedValue;
columnNameValue.ToLower();
SqlCommand searchCommand = new SqlCommand();
searchCommand.Connection = connection;
//Put the column name directly in the request, but use a parameter for the search value
searchCommand.CommandText = "select firstname AS FirstName,lastname AS LastName, zipcode as ZipCode, phone AS Phone, email AS Email, cancersurvivor AS CancerSurvivor, ethnicity AS Ethnicity from registrants where " + columnNameValue + " = #searchterm";
/* No need for this part
SqlParameter columnParam = new SqlParameter();
columnParam.ParameterName = "#columnname";
columnParam.Value = columnNameValue;
*/
SqlParameter searchBoxParam = new SqlParameter();
searchBoxParam.ParameterName = "#searchterm";
searchBoxParam.Value = searchBoxValue;
//searchCommand.Parameters.Add(columnParam);
searchCommand.Parameters.Add(searchBoxParam);
UpdateTable(searchCommand);
}
Your issue is in how you're trying to make your column name as a parameter. You'll want to change the query as a whole to reflect which column you want to filter by. Try the following:
protected void SearchButton_Click(object sender, EventArgs e)
{
string searchBoxValue = SearchBox.Text;
string columnNameValue = ColumnName.SelectedValue;
columnNameValue.ToLower();
SqlCommand searchCommand = new SqlCommand();
searchCommand.Connection = connection;
searchCommand.CommandText = String.Format("select firstname AS FirstName,lastname AS LastName, zipcode as ZipCode, phone AS Phone, email AS Email, cancersurvivor AS CancerSurvivor, ethnicity AS Ethnicity from registrants where {0} = #searchterm",columnNameValue);
SqlParameter searchBoxParam = new SqlParameter();
searchBoxParam.ParameterName = "#searchterm";
searchBoxParam.Value = searchBoxValue;
searchCommand.Parameters.Add(columnParam);
searchCommand.Parameters.Add(searchBoxParam);
UpdateTable(searchCommand);
}
If you want this to work, you'd have to build the SQL statment dynamically and execute with sp_executesql inside the proc as so:
DECLARE #IntVariable int;
DECLARE #SQLString nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
/* Build the SQL string one time.*/
SET #SQLString =
N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID
FROM AdventureWorks2012.HumanResources.Employee
WHERE BusinessEntityID = #BusinessEntityID';
SET #ParmDefinition = N'#BusinessEntityID tinyint';
/* Execute the string with the first parameter value. */
SET #IntVariable = 197;
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#BusinessEntityID = #IntVariable;
/* Execute the same string with the second parameter value. */
SET #IntVariable = 109;
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#BusinessEntityID = #IntVariable;
You still have the benefit of using parametrized queries and not exposing yourself to SQL Injection.
Source here.
Another very useful link is this.
I have few textboxes whose values are to be inserted into SQl table on Submit button click. But it gives me "Object reference not set to an instance of an object" Exception. Below is the code I have written for this. Please do help me in this.
contact_new.aspx.cs
protected void btnSubmit_Click(object sender, EventArgs e)
{
DateTime dtime;
dtime = DateTime.Now;
string ocode = offercode.Text;
string firstname = firstnamepreapp.Text;
string lastname = lastnamepreapp.Text;
string email = emailpreapp.Text;
string phoneno = phonepreapp.Text;
string timetocall = besttimepreapp.SelectedItem.Value;
string time = dtime.ToString();
//Insert the data into autoprequal table
<--- GIVES ME AN ERROR ON THIS LINE --->
Insert.insertINTOautoprequal(ocode, time, firstname, lastname, email, phoneno, timetocall);
}
Insert.cs (App_code class)
namespace InsertDataAccess
{
public class Insert
{
public Insert()
{
//
// TODO: Add constructor logic here
//
}
public static bool insertINTOautoprequal(string code, string time, string first, string last, string email, string phoneno, string timetocall)
{
bool success = false;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connstring"].ConnectionString);
conn.Open();
string query = "Insert INTO autoprequal(offercode, timeofday, firstname, lastname, emailID, phone, besttimetocall) Values(#offercode, #time, #first, #last, #email, #phoneno, #timetocall);";
SqlCommand cmd = new SqlCommand(query, conn);
try
{
cmd.Parameters.AddWithValue("#offercode", code);
cmd.Parameters.AddWithValue("#time", time);
cmd.Parameters.AddWithValue("#first", first);
cmd.Parameters.AddWithValue("#last", last);
cmd.Parameters.AddWithValue("#email", email);
cmd.Parameters.AddWithValue("#phoneno", phoneno);
cmd.Parameters.AddWithValue("#timetocall", timetocall);
if (cmd.ExecuteNonQuery() == 1) success = true;
else success = false;
return success;
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
}
}
Step through the code, as the error is most likely bubbling up from the SQL insert routine. I woulud guess the connection string is not being pulled from the configuration file, but without stepping through that is a wild guess. I would take time to learn how to debug in Visual Studio, as it will help you easily spot what cannot be a problem so you can focus on what is likely to be the problem.