Issue with Inserting integer and string into SQL Server database c# - c#

I am having trouble inserting the integer value [Question Type] and the string [Question Space] into my database at the same time into the same row. Whenever I click the button and try to execute an error comes up saying:
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Incorrect syntax near '('.
Code:
SqlCommand command5 = new SqlCommand("INSERT INTO ([Question Space], [Question Type]) Questions VALUES ('#QuestionText', '#checkedradiobutton')", connect);
command5.Parameters.AddWithValue("#QuestionText", QuestionText);
command5.Parameters.AddWithValue("#checkedradiobutton", checkedradiobutton);
command5.ExecuteNonQuery();
I would appreciate any help that anyone can give me.
Here's the whole code for the button if you want to see:
private void button1_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;
SqlConnection connect = new SqlConnection(connectionString);
connect.Open();
int checkedradiobutton = 0;
if(radioButton1.Checked)
{
checkedradiobutton = 1;
}
else if(radioButton2.Checked)
{
checkedradiobutton = 2;
}
else if(radioButton3.Checked)
{
checkedradiobutton = 3;
}
string QuestionText = QuestionBox.Text;
SqlCommand command5 = new SqlCommand("INSERT INTO ([Question Space], [Question Type]) Questions VALUES ('#QuestionText', '#checkedradiobutton')", connect);
command5.Parameters.AddWithValue("#QuestionText", QuestionText);
command5.Parameters.AddWithValue("#checkedradiobutton", checkedradiobutton);
command5.ExecuteNonQuery();
}
And my database table:
CREATE TABLE [dbo].[Questions]
(
[QuestionID] INT IDENTITY (1, 1) NOT NULL,
[Actual answer] NVARCHAR (50) NULL,
[Question Space] NVARCHAR (50) NULL,
[Question Type] INT NULL,
PRIMARY KEY CLUSTERED ([QuestionID] ASC)
);

The correct syntax for INSERT INTO is
INSERT INTO <table> (field1, field2, fieldN) VALUES (value1, value2, valueN)
so your command should be written as
SqlCommand command5 = new SqlCommand(#"INSERT INTO Questions
([Question Space], [Question Type]) VALUES
(#QuestionText, #checkedradiobutton)", connect);
Note how the parameters placeholders should not be enclosed in single quotes because doing that you tranform them in literal text. (Inserts the "#QuestionText" string in your [Question Space] field)
Finally, try to avoid AddWithValue, it is a shortcut with numerous drawbacks as you can read in Can we stop using AddWithValue already and in How Data Access Code Affects Database Performance
This is still a single line of code
command5.Parameters.Add("#QuestionText", SqlDbType.NVarChar).Value = QuestionText;

You don't have to wrap parameters with ' inside the query. Start cleaning it and see if it works
SqlCommand command5 = new SqlCommand("INSERT INTO [dbo].[Questions] ([Question Space], [Question Type]) Questions VALUES (#QuestionText, #checkedradiobutton)", connect);
command5.Parameters.AddWithValue("#QuestionText", QuestionText);
command5.Parameters.AddWithValue("#checkedradiobutton", checkedradiobutton);
command5.ExecuteNonQuery();

The INSERT syntax is wrong, the name of the table should go after "INSERT INTO", e.g.:
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
Cheers.

Related

I am receiving an SqlException converting numeric data to numeric //ASP.NET Project in Visual Studio (SECOND UPLOAD)

I am trying to save data from a form page I have created using a method for a button OnClick. The code is below.
protected void SaveButton_Click(object sender, EventArgs e)
{
string query = "INSERT INTO[Loans]([CustName], [LoanAmount], [AnualIntRate], [NumPayments]) VALUES(#CustName, #LoanAmount, #AnualIntRate, #NumPayments)";
SqlConnection cnn = new SqlConnection(#"Data Source=(localdb)\ProjectsV13;Initial Catalog=CheapLoans;Integrated Security=True");
SqlCommand cmd = new SqlCommand(query, cnn);
cmd.Connection = cnn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO[Loans]([CustName], [LoanAmount], [AnualIntRate], [NumPayments]) VALUES(#CustName, #LoanAmount, #AnualIntRate, #NumPayments)";
cmd.Parameters.Add("#CustName", SqlDbType.VarChar, 255).Value = custNameTextBox.Text;
cmd.Parameters.Add("#LoanAmount", SqlDbType.Decimal, 0).Value = decimal.Parse(loanAmtTextBox.Text);
cmd.Parameters.Add("#AnualIntRate", SqlDbType.Decimal, 0).Value = decimal.Parse(annualInterestRateTextBox.Text);
cmd.Parameters.Add("#NumPayments", SqlDbType.Int, 0).Value = Int32.Parse(numPaymentsTextBox.Text);
cnn.Open();
cmd.ExecuteNonQuery(); //This is where the exception is thrown
cnn.Close();
cmd.Parameters.Clear();
Page.ClientScript.RegisterStartupScript(this.GetType(), "Scripts", "<script>alert('Loan data INSERT success!');</script>");
}
The exception reads
"System.Data.SqlClient.SqlException: 'Arithmetic overflow error
converting numeric to data type numeric. The statement has been
terminated.'"
My Sql Loans table is coded as follows:
CREATE TABLE [dbo].[Loans] (
[LoanNum] INT IDENTITY (1, 1) NOT NULL,
[CustName] VARCHAR (50) NOT NULL,
[LoanAmount] DECIMAL (9, 2) NOT NULL,
[AnualIntRate] DECIMAL (3, 3) NOT NULL,
[NumPayments] INT NOT NULL,
PRIMARY KEY CLUSTERED ([LoanNum] ASC));
I have tried multiple methods for using an INSERT SQL statement to send the the data to the database, but every method has given me problems. Even making a string where I concatenate the TextBox.Text for each piece of data from the form directly into the INSERT statement. I am trying to get this method working by tomorrow morning for a school project, and would much appreciate help. I intend on staying up until I can get it working.

Is there an equivalent of the MySQL show columns statement in c# / .net?

I'd like to programmatically get the properties of all columns in a table in a MySQL database. Specifically I'm looking to find if a column is nullable or not so required items can be identified in the user interface written in C# / WPF.
I am using MySqlCommandBuilder.DeriveParameters(command) to identify the columns required in a particular stored procedure. MySqlCommandBuilder.DeriveParameters is not supported, and MySQL does not support making parameters to a stored procedure optional. Parameter.IsNullable always returns false in the list of parameters returned by DeriveParameters.
This is one of the tables in the database:
-- -----------------------------------------------------
-- Table `pacswlibinvtool`.`authorstab`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `pacswlibinvtool`.`authorstab` ;
CREATE TABLE IF NOT EXISTS `pacswlibinvtool`.`authorstab` (
`idAuthors` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`LastName` VARCHAR(20) NOT NULL,
`FirstName` VARCHAR(20) NOT NULL,
`MiddleName` VARCHAR(20) NULL DEFAULT NULL,
`YearOfBirth` VARCHAR(4) NULL DEFAULT NULL,
`YearOfDeath` VARCHAR(4) NULL DEFAULT NULL,
PRIMARY KEY (`idAuthors`, `LastName`, `FirstName`),
UNIQUE INDEX `idAuthors_UNIQUE` (`idAuthors` ASC),
INDEX `LastName` (`LastName` ASC),
INDEX `LastCMFirst` (`LastName` ASC, `FirstName` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = UTF8MB4;
I'd like to be able to identify the columns that can be null in a c# application.
You could use the standard INFORMATION_SCHEMA.COLUMNS to explore the properties of your columns
string cmdText = #"SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_Name = 'authorstab'";
using(MySqlConnection cnn = GetMySqlConnection())
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
DataTable dt = new DataTable();
cnn.Open();
using(MySqlDataReader reader = cmd.ExecuteReader())
dt.Load(reader);
}
Now the DataTable dt is filled with rows that contains, each row, all the info about every column of your table including also a column named IS_NULLABLE of type boolean
Please refer below code -
cn = new SqlConnection("Data Source=.;Initial Catalog=DBName;Integrated Security=True");
cn.Open();
SqlCommand command = new SqlCommand("SELECT COLUMN_NAME,IS_NULLABLE FROM information_schema.columns WHERE TABLE_NAME = 'My_Test_Table' ", cn);
command.ExecuteNonQuery();
var reader = command.ExecuteReader();
while( reader.Read())
{
string str1="Column name is "+ reader.GetString(0) + " Null Allowed : - " + reader.GetString(1);
MessageBox.Show(str1);
}
}

Inserting with an Auto-Incrementing ID

I am inserting into a database using a stored procedure and i am getting the error:
Procedure or function 'sp_Addrecord' expects parameter '#RecordNumber', which was not supplied.
RecordNumber is an auto incrementing ID so i understand id have to omit it from my insert command and specify which columns and where i have to insert to avoid this but i am calling the procedure which is handled by another class so where would i be able to specify this as you would normally say something like this:
SqlCommand cmd = new SqlCommand("INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)", conDatabase);
Here is my code, i avoided the using statement for simplicity of this example:
List<CarRecord> carRecords;
private void Save_Record_Click(object sender, RoutedEventArgs e)
{
SqlConnection conDatabase = new SqlConnection(String.Format(#"Data Source={0};Initial Catalog={1};Persist Security Info=True;User ID={2};Password={3}", SQLFunctions.connectSQL.SQLSERVER_ID, SQLFunctions.connectSQL.SQLDatabaseName, SQLFunctions.connectSQL.SQLServerLoginName, SQLFunctions.connectSQL.SQLServerPassword));
conDatabase.Open();
SqlCommand cmd = new SqlCommand("sp_Addrecord", conDatabase);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();
}
public bool Addrecord(CarRecord DataRecord)
{
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
}
EDIT - Stored Procedure:
USE [SDC Logging]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_Addrecord]
#RecordNumber int,
#Date nvarchar(50),
#Time nvarchar(50),
AS
BEGIN
SET NOCOUNT ON;
WITH [source](RecordNumber, Date, Time)
AS
(
SELECT #RecordNumber, #Date, #Time,
)
MERGE dbo.Bags AS [target] USING [source]
ON [target].Date = [source].Date
WHEN MATCHED THEN UPDATE SET
[target].Date = #Date,
[target].Time = #Time,
WHEN NOT MATCHED THEN
INSERT ( Date, Time, )
VALUES( #Date, #Time, );
SELECT SCOPE_IDENTITY()
END
The error says it all. Your sp_Addrecord has a parameter specified that you are supplying. Basically, the parameters you specify here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
must match the name and datatype of the parameters defined by sp_Addrecord stored procedure. In addition, make sure your stored procedure's query matches this query...
INSERT INTO CARS (carDate, carTime) Values (#Date, #Time)
Edit based on your Edit
You need to specified the #RecordNumber parameter here...
return ExecuteNonQuery("sp_Addrecord", null,
CreateParameter("#RecordNumber", SqlDbType.Int, DataRecord.recordNumber),
CreateParameter("#Date", SqlDbType.NVarChar, DataRecord.carDate),
CreateParameter("#Time", SqlDbType.NVarChar, DataRecord.carTime),
);
Don't worry about the insert just make sure that when inserting you pass a "invalid record number" such as -1, if the MERGE statement doesn't find the record with id of -1 it will successfully insert the record with an auto-generated Id with the help of your identity column
Try This.
You don't need to call separate method Addrecord.
However, you still want to use a separate method. Add code below in the AddRecord method and remove existing code:
SqlParameter []parms = new SqlParameter[1];
parms[0] = new SqlParameter("#Date",DataRecord.carDate) ;
parms[1] = new SqlParameter("#Time",DataRecord.carTime) ;
cmd.Parameters.AddRange(parms);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conDatabase.Close();

SQL Identity column if no input value in insert query in ADO.NET throws exception that it can't be null

I have an identity column in the DB which is primary key and increments its value by itself. But I have a insert query in asp.net ado.net class like below:
cmd = new SqlCommand("insert into Images(Name,[Image]) VALUES ('Nature',#img)", conn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text;
cmd.Parameters.Add("#img", SqlDbType.Image).Value = img;
cmd.ExecuteNonQuery();
However, it throws me exception that it cannot be null.
My idea/goal is, I just want to insert the above two values only and the primary key column should increment by itself internally in DB. I have configured that in DB. However I don't know how to handle this error or tweak this code. Please help
Make sure the ID column on your Images table is an identity column.
For example:
CREATE TABLE Images(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](100) NOT NULL,
[Image] [image] NOT NULL)
If it is, then step through your code and make sure the parameters you are using are not null; TextBox1.Text and img.
Lastly, make sure there are no other non-nullable columns on the table.
I think you havn't provided the #Name parameter I your query and but you are sending values in your paramters.
Please remove the 'Nature' value and type #Name.
cmd = new SqlCommand("insert into Images(Name,[Image]) VALUES (#Name ,#img)", conn); cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text;
cmd.Parameters.Add("#img", SqlDbType.Image).Value = img;
cmd.ExecuteNonQuery();

SQL Insert/ Counter Increment

I'm trying to make a program that allows me to store trends in an SQL Table. I need to add a hashtag entered into a textbox into the database if it doesn't already exist, and then increment a counter by 1.
The first column is "HashTag" and the second is "Counter" which has char(10) and int properties respectively.
I'm new to SQL, so it's posing a bit of a problem. This is what I have so far.
SqlConnection connection = new SqlConnection();
connection.ConnectionString = (#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Jordan Moffat\Desktop\coursework\WindowsFormsApplication\WindowsFormsApplication\HashTags.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
connection.Open();
HashTagReader r = new HashTagReader();
if (r.HashTagSearch(s))
MessageBox.Show("I Found it!");
else
{
SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag, Counter) " + "Values (s, ++)", connection);
myCommand.ExecuteNonQuery();
}
connection.Close();
Any suggestions?
Change the Counter column to Identity(1,1) and it will auto increment. You can easily do this through SQL Management Studio.
Then change your query to:
SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag) Values ('" + s + '")", connection);
Note: I believe SqlCommand inherits from DbCommand which implements IDisposable. You should wrap these objects with a using() statement, like so to clean up any unmanaged resources:
using(SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag) Values ('" + s + '")", connection))
{
...
}
If you're on SQL 2008+, you have access to the merge statement. Something like so:
CREATE TABLE #tmp
(
[HashTag] VARCHAR(10) NOT NULL ,
[Counter] INT NOT NULL
);
MERGE [#tmp] AS t
USING
(
SELECT [HashTag] ,
[Counter]
FROM ( VALUES ( '#kitties', 3) ) AS f ( [HashTag], [Counter] )
) AS s
ON t.[HashTag] = s.[HashTag]
WHEN NOT MATCHED BY TARGET
THEN
INSERT ( [HashTag], [Counter] )
VALUES
( s.[HashTag] ,
s.[Counter]
)
WHEN MATCHED
THEN
UPDATE
SET
t.[Counter] += s.[Counter]
OUTPUT
$ACTION ,
INSERTED.* ,
DELETED.*;
I'm using an output clause here just so that it says what it's doing. Execute the merge statement multiple times and see how the output changes. If you're feeling frisky, wrap this in a stored procedure that takes two parameters (hashtag and counter) and you've got yourself something nice. Enjoy!
To add to Chris' answer, to avoid duplicate inserts you should (if you 're on SQL Server 2005 or higher) add a unique index to the HashTag column to enforce the restriction.
Then in the code you should use a WHERE NOT EXISTS clause. See here: SQL Server insert if not exists best practice
So you'd wind up with:
"INSERT INTO tblHashTag (HashTag)
Values ('" + s + "')
WHERE NOT EXISTS (SELECT HashTag
FROM tblHashTag
WHERE HashTag = '" + s + '")"
You can use Parameters to avoid sql injection :
string hashtag = "Your HashTagValue";
string counter = "Your Counter Value";
SqlCommand myCommand = new SqlCommand("INSERT INTO tblHashTag (HashTag, Counter) Values (#HashTag,#Counter)", connection);
myCommand.Parameters.Add("#HashTag", SqlDbType.varchar,50).Value = hashtag; //Your hashTagvalue
myCommand.Parameters.Add("#Counter", SqlDbType.varchar,50).Value = counter; //Your Counter Value
myCommand.ExecuteNonQuery();

Categories

Resources