C# SQL params Insert Query not Working Properly - c#

Okay so I am trying to use parameters in C# sql code block but I am getting #Data in my SQL table please help
string connectionString = #"Network Library=DBMSSOCN;Data Source=**********,1433;database=*******;User id=*****;Password=******;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
//
// Description of SQL command:
// 1. It selects all cells from rows matching the name.
// 2. It uses LIKE operator because Name is a Text field.
// 3. #Name must be added as a new SqlParameter.
//
using (SqlCommand command = new SqlCommand(
"INSERT INTO [dbo].[event_logs] ([event_level],[date_and_time],[source],[event_id],[task_category],[event_data],[channel],[computer_id],[created_at],[updated_at])VALUES('" + entry.EntryType + "','" + entry.TimeWritten + "','" + entry.Source + "','" + entry.InstanceId + "','" + entry.Category + "',' #Data ','" + logtype + "','" + computerID + "','" + DateTime.Now.ToString() + "','" + DateTime.Now.ToString() + "')", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("#Data", entry.Message));
//
// Read in the SELECT results.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
}
}
}

INSERTs don't return results. Use .ExecuteNonQuery() instead of .ExecuteReader().

You are getting #Data because you SQL string is formatted like "',' #Data ','" which is wrong, it is no more a variable, it is itself a SQL String.
What you need to do is fix the SQL query from "',' #Data ','" to "', #Data ,'" it will be fine then.
using (SqlCommand command = new SqlCommand(
"INSERT INTO [dbo].[event_logs] ([event_level],[date_and_time],[source],[event_id],[task_category],[event_data],[channel],[computer_id],[created_at],[updated_at])VALUES('" + entry.EntryType + "','" + entry.TimeWritten + "','" + entry.Source + "','" + entry.InstanceId + "','" + entry.Category + "', #Data ,'" + logtype + "','" + computerID + "','" + DateTime.Now.ToString() + "','" + DateTime.Now.ToString() + "')", connection))
{
// Add new SqlParameter to the command.
command.Parameters.Add(new SqlParameter("#Data", entry.Message));
command.ExecuteNonQuery();
}

You need to specify the name and data type in the constructor, and the value in the new object:
command.Parameters.Add("#Data", SqlDbType.VarChar).Value = entry.Message;

private void button2_Click(object sender, EventArgs e)
{
try
{
string sSQL = "INSERT INTO StuTable (Name, Batch,CGPA, DOB, Program,
Picture)VALUES (#Name, #Batch,#CGPA,#DOB,#Program,#Picture)";
SqlCommand objCmd = new SqlCommand(sSQL, conn);
objCmd.Parameters.Add("#Name", SqlDbType.VarChar, 50);
objCmd.Parameters.Add("#Batch", SqlDbType.Int);
objCmd.Parameters.Add("#CGPA", SqlDbType.Float);
objCmd.Parameters.Add("#DOB", SqlDbType.VarChar, 50);
objCmd.Parameters.Add("#Program", SqlDbType.VarChar, 50);
objCmd.Parameters.Add("#Picture", SqlDbType.VarChar, 500);
//objCmd.Parameters["#RegdNo"].Value = Convert.ToInt32(textBox3.Text);
objCmd.Parameters["#Name"].Value = textBox4.Text;
objCmd.Parameters["#Batch"].Value = textBox5.Text;
objCmd.Parameters["#CGPA"].Value = textBox6.Text;
objCmd.Parameters["#DOB"].Value = maskedTextBox1.Text;
objCmd.Parameters["#Program"].Value = textBox8.Text;
objCmd.Parameters["#Picture"].Value = textBox9.Text;
objCmd.ExecuteNonQuery();
// MessageBox.Show("Record Added");
}
catch (Exception te)
{
MessageBox.Show(te.Message.ToString());
}
}

Related

How Would I Add a Date To Microsoft Access?

I am having issues adding dates/times to Microsoft Access, this is my code:
private void submit_Click(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "insert into DailyLog (EmployeeID,BusNumber,RouteID,DestinationID,ActivityID,Date,MilesDriven,GasInGallons,Comments) values('"+ employee.SelectedValue + "','" + bus.SelectedValue + "','" + route.SelectedValue + "','" + dest.SelectedValue + "','" + activity.SelectedValue + "','" + theDate.Value.ToString("MM/dd/yyyy") + "','" + miles.Value + "','" + gas.Value + "','" + comments.Text + "')";
command.ExecuteNonQuery();
MessageBox.Show("Your log has been submitted.");
connection.Close();
}
catch(Exception ex)
{
MessageBox.Show("Err: " + ex);
connection.Close();
}
}
It is giving me a syntax error for the "Date" only. What should I do? I've tried fixing up the properties, making it a short date, general date, etc. Nothing seems to be working for me.
Exact Error:
Try parameterizing your command. This will take care of any potential SQL injection problems as well as correctly formatting the values for the DBMS.
string commandText = "insert into DailyLog (EmployeeID,BusNumber,RouteID,DestinationID,ActivityID,Date,MilesDriven,GasInGallons,Comments) values(#employee, #bus, #route, #dest, #activity, #theDate, #miles, #gas, #comments)";
using (OleDbCommand command = new OleDbCommand(commandText, connection)) {
// add parameters
command.Parameters.Add(new OleDbParameter("#employee", OleDbType.Integer));
command.Parameters.Add(new OleDbParameter("#theDate", OleDbType.DBDate));
// set parameter valuess
command.Parameters["#employee"] = employee.SelectedValue;
command.Parameters["#theDate"] = theDate.Value;
// execute command
command.ExecuteNonQuery();
}
Updated to remove AddWithValue.

C# Update in ado.net

Old records are not deleting. Update acts like insert.
cn.Open();
string gen;
if (radioButton1.Checked == true)
gen = "Male";
else
gen = "Female";
string clas = null;
clas = comboBox1.Text;
string section = null;
section = comboBox2.Text;
SqlCommand cmd = new SqlCommand("update studetail set name='" + textBox2.Text + "','" + gen + "','" + textBox3.Text + "','" + clas + "','" + section + "' where studentno='" + textBox1.Text + "'");
cmd.Connection = cn;
int n = cmd.ExecuteNonQuery();
update acts like insert.
That's obvious cause you made it like so. Your below UPDATE statement is syntactically wrong
update studetail set name='" + textBox2.Text + "','" + gen + "','" + textBox3.Text + "','" + clas + "','" + section
It rather should be
update studetail set name='" + textBox2.Text + "',' gender = " + gen + "','" ...
Finally, you should consider using parameterized queries instead of concatanating user input likewise you are doing. It's prone to SQL Injection
SqlCommand cmd = new SqlCommand("update studetail set name= #name, gender = #gender, clas = #clas, section = #section where studentno = #studentno");
cmd.Parameters.Add(new SqlParameter("name", textBox2.Text));
cmd.Parameters.Add(new SqlParameter("gender", gen));
cmd.Parameters.Add(new SqlParameter("clas", clas));
cmd.Parameters.Add(new SqlParameter("section", section));
cmd.Parameters.Add(new SqlParameter("studentno", textBox1.Text));

How do I convert the result of ExecuteScalar() to int?

I am actually trying to get the primary key after the insertion by using ExecuteScalar(). Since it returns the first column of the first row after the insertion. But I am getting 0. I do not know why it is happening. Please help me out.
query = "Insert into Admissions(Admission_date, Student_name, Father_name, Mother_name, DOB, Gender, Address, State, City, Pincode, Admission_for, Previous_school, Fees) values ('" + txtAdmDate.Text + "','" + txtStudentName.Text + "','" + txtFatherName.Text + "','" + txtMotherName.Text + "','" + dob + "','" + gender + "','" + txtAddress.Text + "','" + txtState.Text + "','" + txtCity.Text + "','" + txtPincode.Text + "','" + cmbClass.Text + "','" + txtPreviousSchool.Text + "','" + txtFees.Text + "')";
cmd = new SqlCommand(query, con);
con.Open();
int admid = Convert.ToInt32(cmd.ExecuteScalar());
There are some issues with your code/question.
Your code is vulnerable to SQL Injection attacks. You need to parameterize your queries.
The INSERT statement by design is not meant to return anything, if you want to return the primary key of what you just inserted you need an output parameter in your query (better yet, a stored procedure).
A quick google for "return primary key on sql insert c#" would have given you a ton of results. Your question is asked almost verbatim here. In fact my answer is basically the top answers code (modified for your use).
Here is my answer
//Create an Admission class that represents your data
public static int Save(Admission admission)
{
var conn = DbConnect.Connection();
const string sqlString = "Admissions(Admission_date, Student_name, Father_name, Mother_name, DOB, Gender, " +
"Address, State, City, Pincode, Admission_for, Previous_school, Fees) values (#AdmissionDate, #StudentName, " +
"#FatherName, #MotherName, #DOB, #Gender, #Address, #State, #City, #Pincode, #AdmissionFor, #PreviousSchool, " +
"#Fees) SELECT SCOPE_IDENTITY()";
using (conn)
{
using (var cmd = new SqlCommand(sqlString, conn))
{
cmd.Parameters.AddWithValue("#AdmissionDate", admission.AdmissionDate);
cmd.Parameters.AddWithValue("#StudentName", admission.StudentName);
cmd.Parameters.AddWithValue("#FatherName", admission.FatherName);
cmd.Parameters.AddWithValue("#MotherName", admission.MotherName);
cmd.Parameters.AddWithValue("#DOB", admission.DOB);
cmd.Parameters.AddWithValue("#Gender", admission.Gender);
cmd.Parameters.AddWithValue("#Address", admission.Address);
cmd.Parameters.AddWithValue("#State", admission.State);
cmd.Parameters.AddWithValue("#City", admission.City);
cmd.Parameters.AddWithValue("#Pincode", admission.Pincode);
cmd.Parameters.AddWithValue("#AdmissionFor", admission.AdmissionFor);
cmd.Parameters.AddWithValue("#PreviousSchool", admission.PreviousSchool);
cmd.Parameters.AddWithValue("#Fees", admission.Fees);
cmd.CommandType = CommandType.Text;
conn.Open();
return (int)(decimal)cmd.ExecuteScalar();
}
}
}
Try using an OUTPUT clause in your SQL command to return information about your command.
public int NewProperty(PropertyData propertyData)
{
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("InsertUpdateProperty", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", propertyData.ID);
cmd.Parameters.AddWithValue("#ListPropertyFor", propertyData.ListPropertyFor);
cmd.Parameters.AddWithValue("#PropertyTypeId", propertyData.PropertyTypeId);
cmd.Parameters.AddWithValue("#PropertyLoction", propertyData.PropertyLocation);
cmd.Parameters.AddWithValue("#Locality", propertyData.Locality);
cmd.Parameters.AddWithValue("#ProjectName", propertyData.ProjectName);
cmd.Parameters.AddWithValue("#PropertyDescription", propertyData.PropertyDescription);
cmd.Parameters.AddWithValue("#SuperBulidupArea", propertyData.SuperBulidupArea);
cmd.Parameters.AddWithValue("#SuperBulidupId", propertyData.SuperBulidupAreaId);
cmd.Parameters.AddWithValue("#BulidupArea", propertyData.BulidupArea);
cmd.Parameters.AddWithValue("#BulidupAreaId", propertyData.BulidupAreaId);
cmd.Parameters.AddWithValue("#CarpetArea", propertyData.CarpetArea);
cmd.Parameters.AddWithValue("#CarpetAreaId", propertyData.CarpetAreaId);
cmd.Parameters.AddWithValue("#Bathrooms", propertyData.Bathrooms);
cmd.Parameters.AddWithValue("#Bedrooms", propertyData.Bedrooms);
cmd.Parameters.AddWithValue("#Balconies", propertyData.Balconies);
cmd.Parameters.AddWithValue("#FurnishedId", propertyData.FurnishedId);
cmd.Parameters.AddWithValue("#TotalFloors", propertyData.TotalFloors);
cmd.Parameters.AddWithValue("#PropertyOnFloors", propertyData.PropertyOnFloor);
cmd.Parameters.AddWithValue("#Parking", propertyData.Parking);
cmd.Parameters.AddWithValue("#AvalibiltyId", propertyData.AvalibiltyId);
cmd.Parameters.AddWithValue("#AgeOfProperty", propertyData.AgeOfProperty);
cmd.Parameters.AddWithValue("#OwnerShip", propertyData.OwenerShip);
cmd.Parameters.AddWithValue("#Price", propertyData.Price);
cmd.Parameters.AddWithValue("#IsActive", propertyData.IsActive);
con.Open();
int i = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
return i;
}
}

how do i get id of the last inserted row

i want to display booking id of the last inserted row.my insert code is given below. pls anyone can give me code to display the id
protected void Button1_Click(object sender, EventArgs e)
{
string cs = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd;
SqlDataReader dr;
con.Open();
cmd = new SqlCommand("insert into [booking] values('" + TextBox1.Text + "','" + TextBox2.Text + "','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','" + TextBox6.Text + "','" + TextBox7.Text + "','" + TextBox8.Text + "','" + TextBox9.Text + "','" + TextBox10.Text + "','" + TextBox11.Text + "')", con);
cmd.ExecuteNonQuery();
}
}
I would suggest using something like this:
protected void Button1_Click(object sender, EventArgs e)
{
var cs = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
using (var con = new SqlConnection(cs))
{
con.Open();
var cmd = new SqlCommand(
"DECLARE #IDReturnTable TABLE( ID INT ); INSERT INTO [booking] OUTPUT INSERTED.NameOfYourIdColumn INTO #IDReturnTable VALUES(#param1, #param2, #param3); SELECT ID FROM #IDReturnTable",
con);
cmd.Parameters.Add("#param1", SqlDbType.VarChar).Value = TextBox1.Text;
cmd.Parameters.Add("#param2", SqlDbType.VarChar).Value = TextBox2.Text;
cmd.Parameters.Add("#param3", SqlDbType.VarChar).Value = TextBox3.Text;
var returnedId = cmd.ExecuteScalar();
}
}
I didn't use all 11 Text Boxes, just 3 to illustrate the technique.
You will be better off doing this as a stored procedure, and less susceptible to injection.
To achieve it with your current code, add a call to ;SELECT SCOPE_IDENTITY():
cmd = new SqlCommand("insert into [booking] values('" + TextBox1.Text + "','" + TextBox2.Text + "','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','" + TextBox6.Text + "','" + TextBox7.Text + "','" + TextBox8.Text + "','" + TextBox9.Text + "','" + TextBox10.Text + "','" + TextBox11.Text + "');SELECT SCOPE_IDENTITY()", con);
And execute as scalar:
var id = cmd.ExecuteScalar();
(This assumes you have an identity column on your table)
To do it as a stored procedure:
If you have a finite number of values, you can just create the stored procedure normally, with an #Parameter for each TextBox.Text but with SELECT SCOPE_IDENTITY() at the end.
But it looks like you have a variable number of inputs, so see How to insert a multiple rows in SQL using stored procedures? which outlines an approach using a table paramater and one using a UDF to split a list of values.
Again, you would need to SELECT SCOPE_IDENTITY() at the end of the proc to pick up the identity of the last row.
For a detailed discussion on the ways of selecting the last inserted id see What is the difference between Scope_Identity(), Identity(), ##Identity, and Ident_Current?

Insert record(s) DB from Form

I have an Access DB connected to my form with that code ( C# ) :
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data source= Z:\Tempesta\Area Progetto\Area_Progetto_20_02_2014\Area_Progetto_DATA_MAGAZINE\Data_Magazine\Data_Magazine\DB\DataMG.mdb";
try
{
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "INSERT into Prodotti ([Codice],[Descrizione],[Marchio],[Deposito],[Note],[NumeroProdotti],[PrzListinoBase_Aq],[PrzListinoBase_Ve],[Categoria],[Posizione],[Disponibilita],[QtaVenduta],[QtaAcquistata]) VALUES ('" + this.Codice.Text + "','" + this.Descr.Text + "','" + this.Marchio.Text + "','" + this.Deposito.Text + "'," + this.Note.Text + "," + this.NumProd.Text + "," + this.PrzListAcq.Text + "," + this.PrzListVen.Text + ",'" + this.Categ.Text + "','" + this.Posiz.Text + "'," + this.Disp.Text + "," + this.QtaVen.Text + "," + this.QtaAcq.Text + ")";
cmd.Connection = conn;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
// MessageBox.Show("Connessione Fallita!");
conn.Close();
}
finally
{
conn.Close();
}
The error I get when i click the buttton is this one :
Any ideas?
You are missing single quotations in Insert Statement where you are assigning values to columns. Your code is vulnerable so should avoid this here is a useful link.
Are Parameters really enough to prevent Sql injections?
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data source= Z:\Tempesta\Area Progetto\Area_Progetto_20_02_2014\Area_Progetto_DATA_MAGAZINE\Data_Magazine\Data_Magazine\DB \DataMG.mdb";
try
{
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "INSERT into Prodotti (Codice,Descrizione,Marchio,Deposito,Note,NumeroProdotti,PrzListinoBase_Aq,PrzListinoBase_Ve,Categoria,Posizione,Disponibilita,QtaVenduta,QtaAcquistata) VALUES('" + this.Codice.Text + "','" + this.Descr.Text + "','" + this.Marchio.Text + "','" + this.Deposito.Text + "','" + this.Note.Text + "','" + this.NumProd.Text + "','" + this.PrzListAcq.Text + "','" + this.PrzListVen.Text + "','" + this.Categ.Text + "','" + this.Posiz.Text + "','" + this.Disp.Text + "','" + this.QtaVen.Text + "','" + this.QtaAcq.Text + "')";
conn.Open();
cmd.Connection = conn;
cmd.ExecuteNonQuery();
conn.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
// MessageBox.Show("Connessione Fallita!");
conn.Close();
}
finally
{
conn.Close();
}
I don't know italian (is that even the language? :) ) but from the look of it it could very well be a culture settings problem. If, for example, one of your fields is numeric then the database might expect a different decimal separator than the one in use in your UI.
Also your actual design seems very vulnerable to SQL Injection Attacks.
For these reasons, my suggestion is that you use the command's Parameters collection to set your values rather than trying to pass in a concatenated string.
I don't read the language you are posting the error from, however, it looks like a syntax error somewhere in your SqlCommand.
First thing I would suggest is wrapping your connection and command in using blocks to make sure they get disposed of correctly.
Then ALWAYS user parametarized SQL Commands to avoid SQL Injection:
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data source= Z:\Tempesta\Area Progetto\Area_Progetto_20_02_2014\Area_Progetto_DATA_MAGAZINE\Data_Magazine\Data_Magazine\DB\DataMG.mdb"))
using (var cmd = new System.Data.OleDb.OleDbCommand())
{
cmd.CommandText = "INSERT INTO TableName (column1, column2, column3) VALUES (#Value1, #Value2, #Value3)";
cmd.Parameters.AddWithValue("#Value1", this.TextBox1.Text);
cmd.Parameters.AddWithValue("#Value2", this.TextBox2.Text);
cmd.Parameters.AddWithValue("#Value3", this.TextBox3.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
Generally speaking, using parameters eliminates syntax errors because it makes the command much easier to read in it's string representation.
I think you may be missing single quotes around some of your text qualifiers in your INSERT statement.
"INSERT into Prodotti ([Codice],[Descrizione],[Marchio],[Deposito],[Note],[NumeroProdotti],[PrzListinoBase_Aq],[PrzListinoBase_Ve],[Categoria],[Posizione],[Disponibilita],[QtaVenduta],[QtaAcquistata]) VALUES ('" + this.Codice.Text + "','" + this.Descr.Text + "','" + this.Marchio.Text + "','" + this.Deposito.Text + "'," + this.Note.Text + "," + this.NumProd.Text + "," + this.PrzListAcq.Text + "," + this.PrzListVen.Text + ",'" + this.Categ.Text + "','" + this.Posiz.Text + "'," + this.Disp.Text + "," + this.QtaVen.Text + "," + this.QtaAcq.Text + ")";
Consider using a parameterized query rather than building your query string by hand. Not only is it safer, but it can help to weed out these kinds of errors which can be tedious to debug.
eg.
String StrSQL = "INSERT INTO tblLog ([Part_Number],[Quantity],[Date],[LOC_Warehouse],[LOC_Row],[LOC_Section],[LOC_Level],[LOC_Bin],[Stock_Added],[Stock_Removed],[Quarantine_Set],[Quarantine_Removed])"
+ "VALUES(#Part_Number, #Quantity, #Date, #Warehouse, #Row, #Section, #Level, #Bin, #Stock_Added, #Stock_Removed, #Quarantine_Set, #Quarantine_Removed)";
SqlConnection conn = new SqlConnection(WHITS.Properties.Settings.Default.LocalConnStr);
SqlCommand cmd = new SqlCommand(StrSQL, conn);
cmd.Parameters.AddWithValue("#Part_Number", Part_Number);
cmd.Parameters.AddWithValue("#Quantity", Quantity);
cmd.Parameters.AddWithValue("#Date", DateTime.Now);
//More Parameters... Skipped for brevity.
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Open your connection earlier. Also, use "using". Here's how I would do it:
try
{
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data source= Z:\Tempesta\Area Progetto\Area_Progetto_20_02_2014\Area_Progetto_DATA_MAGAZINE\Data_Magazine\Data_Magazine\DB\DataMG.mdb";
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connectionString))
{
conn.Open();
string insertQuery = "INSERT into Prodotti ([Codice],[Descrizione],[Marchio],[Deposito],[Note],[NumeroProdotti],[PrzListinoBase_Aq],[PrzListinoBase_Ve],[Categoria],[Posizione],[Disponibilita],[QtaVenduta],[QtaAcquistata]) VALUES ('" + this.Codice.Text + "','" + this.Descr.Text + "','" + this.Marchio.Text + "','" + this.Deposito.Text + "'," + this.Note.Text + "," + this.NumProd.Text + "," + this.PrzListAcq.Text + "," + this.PrzListVen.Text + ",'" + this.Categ.Text + "','" + this.Posiz.Text + "'," + this.Disp.Text + "," + this.QtaVen.Text + "," + this.QtaAcq.Text + ")";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(insertQuery, conn);
cmd.CommandType = System.Data.CommandType.Text;
cmd.ExecuteNonQuery();
conn.Close();
}
}
Edit: My bad... the code I was referencing was filling a DataAdapter, which doesn't require a call to connection.Open(). Regular querying does. My apologies... I have edited my suggestion.

Categories

Resources