string query = "select a.Name,a.Add from GroupDetails a join General b on a.ID=b.Id where b.AccCode='" + label1.text + "'";
OleDbCommand cmd = new OleDbCommand(query, con);
OleDbDataAdapter daName = new OleDbDataAdapter(cmd);
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
txtName.Text = dr["a.Name"].ToString();
txtAdd.Text = dr["a.Add"].ToString();
}
There shows an exception
Syntax error in FROM clause
If it explicitly mentions from, then my guess would be that the SQL backend doesn't support aliases (the a). However, there are multiple problems:
the alias
the sql concatenation
the unnecessary adapter
the incorrect columns being read
I would suggest trying:
const string query = "select GroupDetails.Name,GroupDetails.Add from GroupDetails join General on GroupDetails.ID=General.Id where General.AccCode=#accCode";
using(var cmd = new OleDbCommand(query, con))
{
cmd.Parameters.AddWithValue("accCode", label1.text);
using(var dr = cmd.ExecuteReader())
{
txtName.Text = (string)dr["Name"];
txtAdd.Text = (string)dr["Add"];
}
}
I'm sure that your query is not SQL Server because it works OK in SQL Server query window. It could be Access SQL or My SQL, and you have to specify explicitly left join, right join or inner join. I think you want inner join in this case:
string query = "SELECT a.Name,a.Add FROM GroupDetails a INNER JOIN General b ON a.ID=b.Id WHERE b.AccCode='" + label1.text + "'";
Add is the Keyword of SQL, you can [] the field like a.[Add]
string query = "select a.Name,a.[Add] from GroupDetails a join General b on a.ID=b.Id where b.AccCode='" + label1.text + "'";
Related
These are the two set up tables
LOGIN TABLE
USER'S NAME
I want to create something like the User will key in their USER_ID and USER_PWD in a textbox. IF the user successfully login, it will say " HI + PATNAME ".
I have created this code so far but it isnt working.
string sqlStr = "Select patpro.'PATNAME' FROM patpro,useform where USER_ID=#name and USER_PWD=#password and useform.'USER_ID' = patpro.'USERID'";
cmd.Parameters.AddWithValue("#name", txtValue.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Password);
cmd.CommandText = sqlStr;
cmd.Connection = connection;
connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
if (login.HasRows)
{
login.Read();
string name = (login["USER_ID"].ToString());
txtAssignID1.Text = "Login verified. Hi, " + name + "\n";
}
From what I see, you're trying to use login["USER_ID"].ToString() which USER_ID is a nonexistent column definition inside current SELECT statement. Hence, you should add column names which defined in SELECT results like login["PATNAME"] and use proper INNER JOIN statement instead:
string sqlStr = #"SELECT patpro.PATNAME FROM patpro INNER JOIN useform
ON useform.USER_ID = patpro.USERID
WHERE useform.USER_ID = #name AND useform.USER_PWD = #password";
cmd.Parameters.AddWithValue("#name", txtValue.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Password);
cmd.CommandText = sqlStr;
cmd.Connection = connection;
connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
if (login.HasRows)
{
// read value inside the loop, because MySqlDataReader is forward-only
while (login.Read())
{
string name = login["PATNAME"].ToString();
txtAssignID1.Text = "Login verified. Hi, " + name + "\n";
}
}
Additional note: Better to use using statement for MySqlConnection, MySqlCommand and MySqlDataReader to ensure immediate disposal of MySQL connection objects after fetching query results.
OleDbConnection connection = new OleDbConnection(#"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = E:\Computing\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\Database31.accdb");
connection.Open();
OleDbCommand command = new OleDbCommand("SELECT Cocktails.CID, Ingredients.Ingredient1" +
" FROM Cocktails INNER JOIN Ingredients" +
" ON Cocktails.ID = Ingredients.ID" +
" WHERE Cocktails.ID = 1",
connection);
OleDbDataReader reader = command.ExecuteReader();
if (reader.Read())
{
string result = reader.GetValue(0).ToString();
string result2 = reader.GetValue(1).ToString();
MessageBox.Show(result + result2);
}
connection.Close();
I'm new to SQL and trying to pull information from two different tables using an 'inner join', : 'Syntax error in JOIN operation.'
is the error I'm getting and unsure why. Thanks
Cocktail and Ingredient must be Cocktails and Ingredients, just like you have them in the FROM ... INNTER JOIN line
The table names you specified is wrong.
ON Cocktails.ID = Ingredients.ID
I am new to Programming and I started with C# (Visual Studio 2017 CE);
I am writing an application and using a DataGrid. I am trying to fill the DataGrid using a query to a C# service based DB (mdf file).
When I run the app and try the query statement I get this error:
Operand type clash: date is incompatible with int
at the SqlDataReader Line.
I have tested the SQL Select statement in the SQL Server and it works there. I have read multiple questions related to the error, but since I am a rookie to programming almost all answers are difficult to understand, Thanks in advance for your understanding
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago = " + Dtp_fecha_cuadre.Text;
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string Nombres = dr["Nombres"].ToString();
string Apellidos = dr["Apellidos"].ToString();
string num_prestamo = dr["prestamo_id"].ToString();
DateTime fecha = Convert.ToDateTime(dr["fecha"].ToString());
double Monto_prestamo = Convert.ToDouble(dr["Monto_prestamo"].ToString());
string Codigo_ruta = dr["Ruta"].ToString();
string Quotas = dr["Quotas"].ToString();
double Balance = Convert.ToDouble(dr["Balance"].ToString());
double Monto_pago = Convert.ToDouble(dr["Monto_pago"].ToString());
double Mora = Convert.ToDouble(dr["Mora"].ToString());
Dgv_cuadre_rutas.Rows.Add(Nombres, Apellidos, num_prestamo, fecha,Monto_prestamo , Codigo_ruta, Quotas, Balance, Monto_pago, Mora);
}
conn.Close();
}
Uses SQL DataAdapter instead which is much easier and will get rid of error
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago = " + Dtp_fecha_cuadre.Text;
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter(strsql, conn);
DataTable dt = new DataTable();
adapter.Fill(dt);
Dgv_cuadre_rutas.DataSource = dt;
conn.Close();
}
I was able to fix the error! the error occurs first because in my original query I was using " = " + Dtp_fecha_cuadre.Text;" the equal sends the data in an int format, so I had to change it to "--like '" + Dtp_fecha_cuadre.Value.ToString() +"'";,-- but at this point it was not filling up the datagrid, then I came up with the idea that, date string being send was not in the correct format, and adjusted the query to "like '" + Dtp_fecha_cuadre.Value.ToString("yyyy-MM-dd") +"'"; and this solve my problem, thanks all that helped me here – engel 1 min ago edit
using (SqlConnection conn = Conexion.Conectado())
{
string strsql = "SELECT dbo.Personas.Nombres, dbo.Personas.Apellidos, dbo.Prestamo.prestamo_id, dbo.Prestamo.fecha, dbo.Prestamo.Monto_prestamo, dbo.Prestamo.Ruta, dbo.Prestamo.Quotas, dbo.Prestamo.Balance, dbo.Registro_pagos.Monto_pago, dbo.Registro_pagos.Mora FROM dbo.Personas INNER JOIN dbo.Prestamo ON dbo.Personas.Persona_id = dbo.Prestamo.fk_Persona_id INNER JOIN dbo.Registro_pagos ON dbo.Prestamo.prestamo_id = dbo.Registro_pagos.fk_prestamo_id where dbo.Registro_pagos.fecha_pago like '" + Dtp_fecha_cuadre.Value.ToString("yyyy-MM-dd") +"'";
SqlCommand cmd = new SqlCommand(strsql, conn);
cmd.CommandType = CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string Nombres = dr["Nombres"].ToString();
string Apellidos = dr["Apellidos"].ToString();
string num_prestamo = dr["prestamo_id"].ToString();
DateTime fecha = Convert.ToDateTime(dr["fecha"].ToString());
double Monto_prestamo = Convert.ToDouble(dr["Monto_prestamo"].ToString());
string Codigo_ruta = dr["Ruta"].ToString();
string Quotas = dr["Quotas"].ToString();
double Balance = Convert.ToDouble(dr["Balance"].ToString());
double Monto_pago = Convert.ToDouble(dr["Monto_pago"].ToString());
double Mora = Convert.ToDouble(dr["Mora"].ToString());
Dgv_cuadre_rutas.Rows.Add(Nombres, Apellidos, num_prestamo, fecha, Monto_prestamo, Codigo_ruta, Quotas, Balance, Monto_pago, Mora);
}
conn.Close();
I can use this loop to give me list of names:
string commandText = #"SELECT ....;";
string connectionString = ConfigurationSettings.AppSettings["connectionString"];
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
try
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(reader);
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = command.ExecuteReader();
string address = addressreader.GetString(0);
}
}
}
catch (Exception ex)
{
}
}
so the dt.Rows[i][0].ToString() is the name I need to add to all my different sql commands. So inside that for loop I will get each value from executing each sql command, one by one:
SqlCommand addresscommand = new SqlCommand(address, connection);
addresscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader addressreader = addresscommand.ExecuteReader();
string comaddress = addressreader.GetString(0);
SqlCommand keyProcessescommand = new SqlCommand(keyProcesses, connection);
keyProcessescommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader keyProcessesreader = keyProcessescommand.ExecuteReader();
string comkeyProcesses = keyProcessesreader.GetString(0);
SqlCommand standardscommand = new SqlCommand(standards, connection);
standardscommand.Parameters.AddWithValue("#companyName", dt.Rows[i][0].ToString());
SqlDataReader standardsreader = standardscommand.ExecuteReader();
string comstandards = standardsreader.GetString(0);
Where the command string determined by:
string address = #"SELECT address FROM Companies where companyName = #companyName";
string keyProcesses = #" SELECT distinct STUFF((SELECT ', '+ cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN KeyProcesses u ON u.categorySetId = uc.setId
INNER JOIN Companies c ON c.companyId = u.companyId
WHERE c.companyName = #companyName
ORDER BY cn.name
FOR XML PATH('')), 1, 1, '') AS listStr
FROM WMCCMCategories cnn Group by cnn.name";
string standards = #" SELECT cn.name from WMCCMCategories cn
INNER JOIN CategorySets uc ON uc.categoryId = cn.categoryID
INNER JOIN Companies c ON c.standards = uc.setId
WHERE c.companyName = #companyName";
Can I execute multiple sql commands like above? How is the best way to do that ?
One way you can solve this through JOIN in SQL. However, it may not be right thing to do if it is not representing same columns.
Now in terms of using multiple select in one command. Yes, you can use SqlDataReader with NextResult()
Please see this link:
http://csharp.net-informations.com/data-providers/csharp-multiple-resultsets.htm
My code:
SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
//..........
cmd.CommandText = "SELECT * FROM TempQn WHERE creatorId= '" +
Session["administratorID"].ToString() + "'";
dr = cmd.ExecuteReader();
while (dr.Read())
{
int ids = Int32.Parse(dr["QuestionID"].ToString());
cmd.CommandText = " INSERT INTO Answers (QuestionId,Answer) Select c.QnId, c.Answer From TempAns c Where c.Id = " + ids + " ";
cmd.ExecuteNonQuery(); //this line
}
dr.Close();
The error is:
There is already an open DataReader associated with this Command which must be closed first.
What kind of command should replace the cmd.ExecuteNonQuery();?
You can't execute any further SQL statements as long as the DataReader is "active".
To overcome this, store list of the SQL statements then exeucute them after reading:
cmd.CommandText = "SELECT * FROM Question WHERE SurveyID= '" + sID + "'";
dr = cmd.ExecuteReader();
List<string> arrSQL = new List<string>();
while (dr.Read())
{
int ids = Int32.Parse(dr["QuestionID"].ToString());
arrSQL.Add("INSERT INTO Answers (QuestionId,Answer) Select c.QnId, c.Answer From TempAns c Where c.Id = " + ids + " ");
}
dr.Close();
arrSQL.ForEach(strSQL =>
{
cmd.CommandText = strSQL;
cmd.ExecuteNonQuery();
});
Your current code is vulnerable to SQL injection attacks though and isn't good practice - you better use Parameter instead of injecting value to the raw SQL - here is how to achieve that:
cmd.CommandText = "SELECT * FROM Question WHERE SurveyID=#id";
cmd.Parameters.AddWithValue("#id", sID);
dr = cmd.ExecuteReader();
List<int> arrQuestions = new List<int>();
while (dr.Read())
{
int ids = Int32.Parse(dr["QuestionID"].ToString());
arrQuestions.Add(ids);
}
dr.Close();
cmd.CommandText = "INSERT INTO Answers (QuestionId, Answer) Select c.QnId, c.Answer From TempAns c Where c.Id = #id";
arrQuestions.ForEach(id =>
{
cmd.Parameters["#id"].Value = id;
cmd.ExecuteNonQuery();
});
You already have one command associated with "cmd".
dr = cmd.ExecuteReader();
while (dr.Read())
{
int ids = Int32.Parse(dr["QuestionID"].ToString());
SqlCommand sqlCmd = new SqlCommand("INSERT INTO Answers (QuestionId,Answer) Select c.QnId, c.Answer From TempAns c Where c.Id = " + ids + " ");
sqlCmd.ExecuteNonQuery(); //this line
}
dr.Close();
So Like ive given above create a new command for the insertion.
This single query should do the job (not sure of you exact data model, adapt if required ):
INSERT INTO Answers (QuestionId,Answer)
Select c.QnId, c.Answer
From TempAns c
inner join Question q on c.QnId = q.Id
where q.SurveyID = #SurveyID
In order to avoid SQl Injection, use this C# code :
cmd.CommandTest = #"INSERT INTO Answers (QuestionId,Answer)
Select c.QnId, c.Answer
From TempAns c
inner join Question q on c.QnId = q.Id
where q.SurveyID = #SurveyID";
SqlParameter param = cmd.Parameters.Add("#SurveyID", SqlDbType.Int);
param.Value = yourSurveyId;
cmd.Open(); // it would be better to check the status before
cmd.ExecuteNonQuery();
cmd.Close();
Instead of using a 2nd connection object, you could change your connection string and use MARS (Multiple active result set) for this purpose. Add the following statement to your connection string:
MultipleActiveResultSets=True
EDIT:
And like the other's said, use SqlParameters for your parameters and not string concatenation. It's not only a security issue, but also a huge performance hit!
you need to declare a new command object because cmd is already being used for reading the data when you are trying to use it for insert statement. Also, don't use string concatenation from sql command, its a bad practice and vulnerable to SQL injection. using parameters.