Using '#val3' or #val3 in SQL Server query parameters - c#

I am just wondering what is the correct way for sending this old query statement:
"SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = 1 " +
"AND " +
"StartDate = " + Session["between"] + " " +
"AND " +
"UPPER(I1) = '" + Session["StrUser"].ToString().ToUpper() + "'"
To this way (correct way of passing the parameters):
SqlDataAdapter da = new SqlDataAdapter();
DataSet _ds1 = new DataSet();
String blah = "SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = #val1 " +
"AND " +
"StartDate #val2 " +
"AND " +
"UPPER(I1) = '#val3'"
command = new SqlCommand(blah, con);
command.Parameters.AddWithValue("#val1", 1);
command.Parameters.AddWithValue("#val2", Session["between"].ToString());
command.Parameters.AddWithValue("#val3", Session["StrUser"].ToString().ToUpper());
da = new SqlDataAdapter(command);
da.Fill(_ds1, dbName);
da.Dispose();
closeAllConnections();
command.Parameters.Clear();
return _ds1;
The main focus of this question is the '#val3'" part. Is that needed or will the command.Parameters.AddWithValue automatically place that if needed?

Using parameters is a good way of separating SQL code from data. As such, you should understand that the ' characters are part of a data literal. As such, unless you're wanting to compare I1 with the literal string #val3, and instead want to use the parameter, it should not be enclosed in 's.
This is correct:
String blah = "SELECT " +
"* " +
"FROM " +
"tE " +
"WHERE " +
"active = #val1 " +
"AND " +
"StartDate = #val2 " +
"AND " +
"UPPER(I1) = #val3"
will the command.Parameters.AddWithValue automatically place that if needed?
No, it will not - because you're no longer trying to construct a literal value, no 's are required at all. Parameters aren't just a fancy way of doing text replacement - they keep the code and data separate and, importantly, deal with any required conversions behind the scenes.

Related

SQL Server 2012 : Between issue with parameters

I am having an issue with the query below:
SELECT
tT.RequestID,
TStatus,
TLead,
RequestDate,
tG.Category,
tETM.RAgency,
ECost,
tTT.TType
FROM
tT AS tT
INNER JOIN
tTMain AS tETM ON tT.RequestID = tETM.RequestID
INNER JOIN
tTType AS tTT ON tETM.AMod = tTT.TypeID
INNER JOIN
tGup AS tG ON tT.Category = tG.CategoryID
WHERE
tT.active = 1
AND (ApproxDate BETWEEN '09/30/2016' AND '09/30/2017')
AND tT.Category = 3
I am currently getting an error:
Conversion failed when converting date and/or time from character string.
The way I populate the above query in code:
string theQ = "SELECT " +
"tT.RequestID, " +
"TStatus, " +
"TLead, " +
"RequestDate, " +
"tG.Category, " +
"tETM.RAgency, " +
"ECost, " +
"tTT.TType " +
"FROM " +
"tT AS tT " +
"INNER JOIN " +
"tTMain AS tETM " +
"ON " +
"tT.RequestID = tETM.RequestID " +
"INNER JOIN " +
"tTType AS tTT " +
"ON " +
"tETM.AMod = tTT.TypeID " +
"INNER JOIN " +
"tGup AS tG " +
"ON " +
"tT.Category = tG.CategoryID " +
"WHERE " +
"tT.active = #val1 " +
"AND " +
"(ApproxDate BETWEEN #val2 AND #val3) " +
"AND " +
"tT.Category = #val4"
//Split up the between check. (it looks like this: BETWEEN 'xx/xx/xxxx' AND 'xx/xx/xxxx')
string[] betweenSplit = Regex.Split(Session["between"].ToString(), " AND ");
SqlDataAdapter da = new SqlDataAdapter();
DataSet _ds1 = new DataSet();
command = new SqlCommand(theQ, con);
command.Parameters.AddWithValue(1, "1");
command.Parameters.AddWithValue(2, betweenSplit[0].Replace(" BETWEEN ", ""));
command.Parameters.AddWithValue(3, betweenSplit[1]);
command.Parameters.AddWithValue(4, Session["UCat"].ToString());
da = new SqlDataAdapter(command);
da.Fill(_ds1, dbName);
da.Dispose();
closeAllConnections();
command.Parameters.Clear();
The error occurs on the line:
da.Fill(_ds1, "tripData");
What would I be doing incorrectly because the same query above works just fine when running it in Server Management Studio?
I suggest to avoid implicit conversion of date to/from string.
In your case it could be (for example):
CONVERT (datetime, '09/30/2016',101)
You should pass Datetime parameter to SQL like that
var yourFromDate = DateTime.Now;
SqlParameter fromDate = new SqlParameter("#val2", SqlDbType.DateTime) {Value = yourFromDate};
command.Parameters.Add(fromDate);

MySqlDataAdapter Update table that uses Inner Join

I'm tring to add the Insert, Update and Delete commands to a MySqlDataAdapter which has the data added to it with the command:
//iec211.4521studenti
string lv_sObsTable = "`" + mv_sDatabase + "`.`" + mv_sGroup + "observatii`";
string lv_sStudTable = "`" + mv_sDatabase + "`.`" + mv_sGroup + "studenti'";
string lv_sObservatiiCommand = "SELECT o.idObservatie, o.idStudent, s.nume, o.observatie, o.lastUpdate FROM " + lv_sObsTable + " o INNER JOIN " + lv_sStudTable + " s USING (idStudent) ORDER BY s.nume ASC";
mv_dtAdapterObservatii = new MySqlDataAdapter(lv_sObservatiiCommand, mv_sqlConnection);
mv_dtAdapterObservatii.Fill(mv_dsTables, lv_sCurrentTable);
I've serched for an answer and I've found two possible solutions for UPDATE, but both of them give me an error:
string lv_sObsTB = "`" + mv_sDatabase + "`.`" + mv_sGroup + "observatii`";
string lv_sStudTB = "`" + mv_sDatabase + "`.`" + mv_sGroup + "studenti`";
//VERSION 1
string lv_sCommand = "UPDATE o SET s.idStudent=#idStudent, o.observatie=#observatie FROM " + lv_sObsTB + " AS o INNER JOIN " + lv_sStudTB + " s ON o.idStudent=s.idStudent ";
MySqlCommand lv_sqlCommand = new MySqlCommand(lv_sCommand);
lv_sqlCommand.Parameters.Add("#idStudent", MySqlDbType.Int16, 10, "idStudent");
lv_sqlCommand.Parameters.Add("#observatie", MySqlDbType.VarChar, 255, "observatie");
mv_dtAdapterObservatii.UpdateCommand = lv_sqlCommand;
//VERSION 2
string lv_sCommand = "UPDATE " + lv_sObsTB + " SET " + "idStudent=#" + lv_sStudTB + ".idStudent, observatie=#observatie WHERE idObservatie=#idObservatie AND " + lv_sObsTB + ".idStudent IN (SELECT " + lv_sStudTB + ".idStudent FROM " + lv_sStudTB + ")";
MySqlCommand lv_sqlCommand = new MySqlCommand(lv_sCommand);
lv_sqlCommand.Parameters.Add("#" + lv_sStudTB + ".idStudent", MySqlDbType.Int16, 10, "idStudent");
lv_sqlCommand.Parameters.Add("#observatie", MySqlDbType.VarChar, 255, "observatie");
lv_sqlCommand.Parameters.Add("#idObservatie", MySqlDbType.Int16, 10, "idObservatie");
mv_dtAdapterObservatii.UpdateCommand = lv_sqlCommand;
The error message for the first version is : "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM iec211.4521observatii ASS o INNER JOIN iec211.4521studenti s ON o.id' at line 1"
The error message for the second version is:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.4521studenti'.idStudenti, observatie='test' WHERE idObservatie=1 ANDiec211.' at line 1"
I don't know how to use the MySQL commands in combination with MySqlCommand and MySqlDataAdapter.
Until now I've used the following command to obtain data for my table:
string lv_sObservatiiCommand = "SELECT * FROM `" + mv_sDatabase + "`.`" + mv_sGroup + "observatii` ORDER BY idStudent ASC";
mv_dtAdapterObservatii = new MySqlDataAdapter(lv_sObservatiiCommand, mv_sqlConnection);
mv_dtAdapterObservatii.Fill(mv_dsTables, lv_sCurrentTable);
In combination with MySqlCommandBuilder to get the update command and the parameters that needed to be setted:
lv_sqlCommandBuilder = new MySqlCommandBuilder(mv_dtAdapterObservatii);
mv_dtAdapterObservatii.UpdateCommand = lv_sqlCommandBuilder.GetUpdateCommand();
Can someone please explain to me how to correctly add the insert, update and delete commands to a MySqlDataAdapter that contains an INNER JOIN between 2 tables ?
I know that each table must be in a different data adapter, and they are. The "4521studenti" table is inside "mv_dtAdapterStudenti", which is not included in the code above.
Thank you for the help and I hope this won't be considered as a bad post. :)
Okey. I think I've figured it out.
This is the SELECT command for 4521observatii:
string lv_sStudent = "`" + mv_sDatabase + "`.`" + mv_sGroup + "studenti`";
string lv_sObservatii = "`" + mv_sDatabase + "`.`" + mv_sGroup + "observatii`";
string lv_sObservatiiCommand = "SELECT o.idObservatie, o.idStudent, s.nume, o.observatie, o.lastUpdate FROM " + lv_sObservatii + " o INNER JOIN " + lv_sStudent + " s USING (idStudent) ORDER BY s.nume ASC";
// Read data from the server for the current table and add it to the DataSet
mv_dtAdapterObservatii = new MySqlDataAdapter(lv_sObservatiiCommand, mv_sqlConnection);
mv_dtAdapterObservatii.Fill(mv_dsTables, lv_sCurrentTable);
And this is the code for the UPDATE command, inside a different method:
// `iec211`.`4521observatii`
string lv_sObsTB = "`" + mv_sDatabase + "`.`" + mv_sGroup + "observatii`";
// `iec211`.`4521studenti`
string lv_sStudTB = "`" + mv_sDatabase + "`.`" + mv_sGroup + "studenti`";
string lv_sSelectStudenti = "(SELECT idStudent FROM " + lv_sStudTB + " WHERE idStudent=#idStudent)";
string lv_sCommand = "UPDATE " + lv_sObsTB + " SET idStudent="+ lv_sSelectStudenti + ", observatie=#observatie WHERE idObservatie=#idObservatie";
MySqlCommand lv_sqlCommand = new MySqlCommand(lv_sCommand);
lv_sqlCommand.Parameters.Add("#idStudent", MySqlDbType.Int16, 10, "idStudent");
lv_sqlCommand.Parameters.Add("#observatie", MySqlDbType.VarChar, 255, "observatie");
lv_sqlCommand.Parameters.Add("#idObservatie", MySqlDbType.Int16, 10, "idObservatie");
mv_dtAdapterObservatii.UpdateCommand = lv_sqlCommand;
mv_dtAdapterObservatii.UpdateCommand.Connection = mv_sqlConnection;
The idea is that when I use INNER JOIN I bring data from two different tables and put them together. When I used the UPDATE command, the program didn't know which table he was using and gived those errors.
So I thought what if I update the values of 4521observatii and for the column that is used as FOREIGN KEY I assign the value from 4521studenti.
I know it's like "Tell me your name so I can tell you your name.", but it worked for me.
I hope this will help others and you have a better and cleaner solution, pleas tell me :)

SQL C# WPF Query Expanded

I had a query answered here SQL Select All Without Values in Another Table.
I've just been asked to integrate the data from another database. This is what I have at the moment.
string _loanSubcontractor = TableNames.Default.LoansSubcontractors;
string _loanPacific = TableNames.Default.LoansPacific;
string _tools = TableNames.Default.Tools;
string _selectStatement = " SELECT [Tools].[Type], [Tools].[Brand], [Tools].[Serial], [Tools].[Year], [Tools].[Code] ";
string _groupBy = " GROUP BY [Tools].[Type], [Tools].[Brand], [Tools].[Serial], [Tools].[Year], [Tools].[Code], [Tools].[Working] ";
string _searchItems = " ([Tools].Code LIKE #toolSerial OR [Tools].Serial LIKE #toolSerial) AND ([Tools].[Working] = 'True' OR [Tools].[Working] IS NULL) ";
SqlConnection myConnection = new SqlConnection(Connection.Default.ConnectionString);
//Checks the main tool information
myConnection.Open();
SqlCommand getTool = new SqlCommand(
_selectStatement + "FROM [" + _tools + "] LEFT OUTER JOIN [" + _loanSubcontractor + "] ON " +
_tools + ".code = [" + _loanSubcontractor + "].ToolCode FULL JOIN [" + _loanPacific + "] ON " + _tools + ".Code = " +
_loanPacific + ".ToolCode WHERE [" + _loanSubcontractor + "].ToolCode IS NULL AND [" + _loanPacific + "].ToolCode IS NULL AND (" + _searchItems + ")" +
"UNION " +
_selectStatement + " FROM [" + _loanSubcontractor + "] INNER JOIN " + _tools + " ON " + _tools + ".Code = [" + _loanSubcontractor + "].ToolCode " +
"INNER JOIN " + _loanPacific + " ON " + _loanPacific + ".ToolCode = " + _tools + ".Code " + _groupBy +
"HAVING (COUNT(" + _loanSubcontractor + ".ReturnDate) = COUNT(*) OR COUNT(" + _loanPacific + ".ReturnDate) = COUNT(*)) " +
" AND " + _searchItems, myConnection);
getTool.Parameters.Add("#toolSerial", SqlDbType.NVarChar).Value = "%" + toolSerial + "%";
What I have is two loan tables (one for employees and one for subcontractors) because the attribute names are different and the data types are also different. Essentially, I need to check that the tool is working, and the tool is not hired out in either of the loan tables (as shown by the return date being null). There may or may not be a loan in either of the tables.
Also, could someone provide me with a link that shows good formatting techniques for SQL within C#?
i sagest you use linq to SQL . this is a part of ADO.NET and you can use long query with 100 % acres and easy way
msdn.microsoft.com for linq to SQL
LINQ to SQL: .NET Language-Integrated Query for Relational Data
Simple LINQ to SQL in C#

Read Data from data set

I have data set that is being filled from sql query, like this
cmd_sql.CommandText = " SELECT BrDok " +
" FROM ordersstavke " +
" WHERE SifParFil = '" + rw_mat["sifskl_kor"] + "'";
MySqlDataAdapter sql_adapter = new MySqlDataAdapter(cmd_sql);
DataSet ds_dok = new DataSet("ordersstavke");
sql_adapter.Fill(ds_dok);
Now I want to extract value from data set for sql update, like this one
myQuery = "UPDATE ordersstavke " +
"SET BrDok = '" + rw_mat["brdok"] + "', " +
"SifParFil = '" + rw_mat["sifskl_kor"] + "', " +
"WHERE BrDok = " + ds_dok.Tables["ordersstavke"].Rows[0]["BrDok"] + "'";
I tried this ds_dok.Tables["ordersstavke"].Rows[0]["BrDok"] but I got an error,
I was thinking to do something like this
string BrDok;
BrDok = ds_dok.["BrDok"].ToString();
But nothing, how to extract that BrDok or just put it into procedure?
Thanks infront!
Make it
DataSet ds_dok = new DataSet("ordersstavke");
sql_adapter.Fill(ds_dok,"BrDok");
Then use
ds_dok.Tables["BrDok"].Rows[0]["BrDok"].ToString()
Try this
ds_dok.Tables[0].Rows[0]["BrDok"]
If you provide a string argument for the dataset class, then it will be the dataset name and not the datatable name. And there is no table in the database with name you provided for a dataset, so give it while filling the dataset. Write some thing like below.
DataSet ds_dok = new DataSet();
sql_adapter.Fill(ds_dok,"ordersstavke");
and you can write all the remaining code as it is in your code part.
And your second update query has some syntax error, see it like below
myQuery = "UPDATE ordersstavke " + "SET BrDok = '" + rw_mat["brdok"] + "', "
+ "SifParFil = '" + rw_mat["sifskl_kor"] + "', " + "WHERE BrDok
= '" + ds_dok.Tables["ordersstavke"].Rows[0]["BrDok"] + "'";
You forgot to put an starting inverted comma at the where clause.
Just a small hint to the sql-command. You should use sql-parameters to prefent sql-injection.

How can you use parameterized statements with DB2 Text Search?

I've tried this:
select * from ourschema.mytable
where contains(mysearchablefield, #searchTerms) = 1;
Where #searchTerms was set to "search terms"
Unfortunately, it only produced an error:
ERROR [42610] [IBM][DB2/NT] SQL0418N A statement contains a use of a parameter marker that is not valid. SQLSTATE=42610
Is there a way to use parameterized queries for text search with DB2? If not, is there a document which describes the syntax in detail for manual (ugh) escaping of the search terms (quotes, etc)?
Instead of #field you need to use "?". Everything is basically the same.
Okay, here is a live code sample.
sqlStmt = "SELECT COMPLAINT_NUMBER, VIOLATION_NUMBER, COMMON_ADDRESS_KEY, " +
"DEPT_CODE, DEPT_CODE_DESC, DIVISION_CODE, DIVISION_CODE_DESC, " +
"EMPLOYEE_NAME, COMPLAINT_CODE, COMPLAINT_CODE_DESC, COMPLAINT_DATE, " +
"COMMON_ADDRESS_OWNER, RESOLUTION_CODE, 1 AS SORTORDER " +
"FROM QMFILES/NVMASTP " +
"WHERE VCLOSEDATE = 0 AND " +
"DEPT_CODE LIKE #DEPT_CODE1 AND " +
"DIVISION_CODE LIKE #DIVISION_CODE1 AND " +
"COMPLAINT_DATE BETWEEN #FROM_COMPLAINT_DATE1 AND #TO_COMPLAINT_DATE1 " +
statusQry +
"UNION " +
"SELECT COMPLAINT_NUMBER, VIOLATION_NUMBER, COMMON_ADDRESS_KEY, " +
"DEPT_CODE, DEPT_CODE_DESC, DIVISION_CODE, DIVISION_CODE_DESC, " +
"EMPLOYEE_NAME, COMPLAINT_CODE, COMPLAINT_CODE_DESC, COMPLAINT_DATE, " +
"COMMON_ADDRESS_OWNER, RESOLUTION_CODE, 2 AS SORTORDER " +
"FROM QMFILES/NVMASTP " +
"WHERE VCLOSEDATE <> 0 AND " +
"DEPT_CODE LIKE #DEPT_CODE2 AND " +
"DIVISION_CODE LIKE #DIVISION_CODE2 AND " +
"COMPLAINT_DATE BETWEEN #FROM_COMPLAINT_DATE2 AND #TO_COMPLAINT_DATE2 " +
statusQry +
"ORDER BY DEPT_CODE, DIVISION_CODE, COMPLAINT_CODE, SORTORDER";
iDB2Command cmd = new iDB2Command(sqlStmt, conn);
conn.Open();
cmd.DeriveParameters();
conn.Close();
cmd.Parameters["#DEPT_CODE1"].Value = dept;
cmd.Parameters["#DIVISION_CODE1"].Value = serviceArea;
cmd.Parameters["#DEPT_CODE2"].Value = dept;
cmd.Parameters["#DIVISION_CODE2"].Value = serviceArea;
cmd.Parameters["#FROM_COMPLAINT_DATE1"].Value = Convert.ToDecimal(fromDateString);
cmd.Parameters["#TO_COMPLAINT_DATE1"].Value = Convert.ToDecimal(toDateString);
cmd.Parameters["#FROM_COMPLAINT_DATE2"].Value = Convert.ToDecimal(fromDateString);
cmd.Parameters["#TO_COMPLAINT_DATE2"].Value = Convert.ToDecimal(toDateString);
I hope this helps you out more.

Categories

Resources