parameterized with session and query string - c#

I am facing an error message and i didnt know the reason with me sql statement as at line:
DACatPgeVIPLIST.Fill(dsCatPgeVIPLIST);
It's showing this message can you help me with it:
The parameterized query (#Country nvarchar(7),#Category nvarchar(4000))SELECT a.[AdsID], expects the parameter #Category, which was not supplied.
Code:
if (Session["location"] != null)
{
using (SqlConnection CatPgeVIPLISTsqlCON = new SqlConnection(cs))
{
CatPgeVIPLISTsqlCON.Open();
SqlDataAdapter DACatPgeVIPLIST = new SqlDataAdapter("SELECT a.[AdsID], a.[Country], a.[State], a.[City], a.[AdsTit], SUBSTRING(a.[AdsDesc], 1, 70) as AdsDesc, a.[AdsPrice], a.[Img1] FROM [ads] as a INNER JOIN [UserInfo] as u on u.UID = a.UID WHERE a.[Country] = #Country and a.[Category] = #Category and u.VIP = 'Yes'", cs);
string location = Convert.ToString(Session["location"]);
string category = Request.QueryString["category"];
DACatPgeVIPLIST.SelectCommand.Parameters.AddWithValue("#Country", location);
DACatPgeVIPLIST.SelectCommand.Parameters.AddWithValue("#Category", category);
DataSet dsCatPgeVIPLIST = new DataSet();
DACatPgeVIPLIST.Fill(dsCatPgeVIPLIST);
CatPgeVIPLIST.DataSource = dsCatPgeVIPLIST.Tables[0];
CatPgeVIPLIST.DataBind();
}
}

It's possible for the following line of code to assign null to category:
string category = Request.QueryString["category"];
You could possibly get around it like this, which converts null to an empty string:
string category = Convert.ToString(Request.QueryString["category"]);
Or you could try passing DBNull.Value instead of null (untested):
DACatPgeVIPLIST.SelectCommand.Parameters
.AddWithValue("#Category", (object)category ?? DBNull.Value);

Related

passing columnname with a parameter SQLcommand

I've been googling something I dont really cant understand.
In short my problem is this;
When using this;
String sYear2 = "2020";
string query = #"Select decJan from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
The result is returning "111" (which is correct vaule of column decJan the year 2020.
But when trying this;
String sYear2 = "2020";
String sColumn2 = "decJan";
string query = #"Select " + #column + #" from tbFuGraddagar where intRecnum = (select intRecnum from tbfuGraddagar where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
cmd.Parameters.AddWithValue("#column", sColumn2);
I recieve "decJan" as result.
When googling all I have found that its not possible without dynamic SQL or that is bad design.
But I fail to understand what the diffrence is...all I want is to change the static code with a value similar to #year-parameter. the "interpretation" shouldn't care about the validation of SQL-syntax, it's just a matter och string-manipulation.
Or is it just me beeing a bad C#-coder?
Probably addwithvalue method is not valid for adding dynamic column names in select statements. I think you should use c# 8.0 feature, string interpolation to solve this problem.  You can add column names with string interpolation. Can you try this approach :
String sYear2 = "2020";
string deccan = "decJan";
string query = $(Select {decJan} from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)
query = #query;
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);

Incorrect Syntax near ""

I think my code is correct but why error syntax near 'po_no' check my code please. What is the problem with my code with this kind of error? Do I need to JOIN or two queries? I just want to display the two table using inner join
try
{
if (cb_po_search.Text == "")
{
MessageBox.Show("Please Enter to Search!");
}
else
{
string strPRSconn = ConfigurationManager.ConnectionStrings["POSdb"].ConnectionString;
SqlConnection sc = new SqlConnection(strPRSconn);
sc.Open();
string strQry = "SELECT dbo.POMain.po_no, dbo.POMain.issuing_month, dbo.POMain.supplier, dbo.POMain.model, dbo.POMain.category, dbo.POMain.req_number, dbo.POMain.shipment, dbo.POMain.production_month, dbo.POMain.req_time_arrival, dbo.POMain.req_department, dbo.POMain.lead_time, dbo.POMain.order_desc, dbo.POMain.date_emailed, dbo.POMain.date_confirmed, dbo.POMain.date_recieved, dbo.POMain.assumed_arrival, dbo.Shipping.invoice, dbo.Shipping.loading_date, dbo.Shipping.etd, dbo.Shipping.eta_manila, dbo.Shipping.eta_tstech, dbo.Shipping.ata_tstech, dbo.Shipping.shipping_status, dbo.Shipping.remarks FROM dbo.POMain INNER JOIN dbo.Shipping ON dbo.POMain.po_no = dbo.Shipping.po_noWHERE po_no= '" + cb_po_search.Text + "'";
SqlCommand scmd = new SqlCommand(strQry, sc);
SqlDataAdapter da = new SqlDataAdapter(strQry, sc);
DataTable dt = new DataTable();
SqlDataReader dr = scmd.ExecuteReader();
while (dr.Read())
{
//purchase order
tb_ponumber2.Text = (dr["po_no"].ToString());
tb_reqnumber2.Text = (dr["req_number"].ToString());
cb_supplier2.Text = (dr["supplier"].ToString());
cb_model2.Text = (dr["model"].ToString());
cb_category2.Text = (dr["category"].ToString());
cb_shipment2.Text = (dr["shipment"].ToString());
ta_description2.Text = (dr["order_desc"].ToString());
tb_leadtime2.Text = (dr["lead_time"].ToString());
tb_request2.Text = (dr["req_department"].ToString());
dt_time_arrival2.Value = DateTime.Parse(dr["req_time_arrival"].ToString());
dt_arrival2.Value = DateTime.Parse(dr["assumed_arrival"].ToString());
dt_confirmed2.Value = DateTime.Parse(dr["date_confirmed"].ToString());
dt_email2.Value = DateTime.Parse(dr["date_emailed"].ToString());
dt_production_month2.Value = DateTime.Parse(dr["production_month"].ToString());
dt_recieve2.Value = DateTime.Parse(dr["date_recieved"].ToString());
dt_issuing_month2.Value = DateTime.Parse(dr["issuing_month"].ToString());
}
sc.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Your code is asking for an SQL Injection, use parametized queries instead with SqlParameter class.
Edit. Your query have a missing equals sign at the end. Things that woudn't happen using parametized queries ;-)
http://www.csharp-station.com/Tutorial/AdoDotNet/lesson06

Specified cast is not valid. SQL Parameter

I keep getting back specified cast is not valid on the int result = myDataReader.GetInt32(0); line when running the query using the parameter.
The thing is if I replace #Reg with text 'WM07 OGR' it works fine. However the string reg returns this so why the error?
string reg = RadComboBox1.SelectedValue;
//prepare sql statements
Command = new OleDbCommand(#"SELECT MAX(Fuel.NO_ODOMETER_LAST) AS PrevMiles
FROM (Fuel INNER JOIN Vehicle ON Fuel.TX_VIN = Vehicle.TX_VIN)
WHERE (Vehicle.TX_VEHNUMBER = '#Reg')", conn);
Command.Parameters.AddWithValue("#Reg", OleDbType.WChar);
Command.Parameters["#Reg"].Value = reg;
myDataReader = Command.ExecuteReader();
if (myDataReader.Read())
{
int result = myDataReader.GetInt32(0);
Prev_Mileage.Text = result.ToString();
}
//cleanup objects
myDataReader.Close();
conn.Close();
The thing is if I replace #Reg with text 'WM07 OGR' it works fine.
However the string reg returns this so why the error?
It seems that you get the error if the query returns null because there is no matching TX_VEHNUMBER, then the cast to int fails.
So you have to check if it's null:
int result = 0; // insert default
if(!myDataReader.IsDbNull(0))
result = myDataReader.GetInt32(0)
Apart from that it doesn't work because your parameter is interpreted as value, you have wrapped it in apostrophes here:
WHERE (Vehicle.TX_VEHNUMBER = '#Reg')
You just have to do this:
WHERE (Vehicle.TX_VEHNUMBER = #Reg)
Try some thing like this.
Command = new OleDbCommand(#"SELECT MAX(Fuel.NO_ODOMETER_LAST) AS PrevMiles
FROM (Fuel INNER JOIN Vehicle ON Fuel.TX_VIN = Vehicle.TX_VIN)
WHERE (Vehicle.TX_VEHNUMBER = #Reg)", conn);
Or
Command = new OleDbCommand(#"SELECT MAX(Fuel.NO_ODOMETER_LAST) AS PrevMiles
FROM (Fuel INNER JOIN Vehicle ON Fuel.TX_VIN = Vehicle.TX_VIN)
WHERE (Vehicle.TX_VEHNUMBER = '?')", conn);
Or
Command = new OleDbCommand(#"SELECT MAX(Fuel.NO_ODOMETER_LAST) AS PrevMiles
FROM (Fuel INNER JOIN Vehicle ON Fuel.TX_VIN = Vehicle.TX_VIN)
WHERE (Vehicle.TX_VEHNUMBER = ?)", conn);
For more reference see following links.
http://www.java2s.com/Code/CSharp/Database-ADO.net/PassparametertoOleDbCommand.htm
http://blogs.msdn.com/b/wriju/archive/2008/01/24/ado-net-oledbcommand-parameterized-query-sequence-rule.aspx
Since it's getting into the below block...
if (myDataReader.Read())
{
int result = myDataReader.GetInt32(0);
Prev_Mileage.Text = result.ToString();
}
...I assume you have a record. I'd check the DataType of NO_ODOMETER_LAST, as it might be a varchar or something other than an int. If thats a case, you might need to use a TryParse.

sending null value with parametrized queries

public static DataTable GetBatches(long storeID, long? ProfileID)
{
string query =
"SELECT .... where " + (ProfileID.HasValue ? "PROFILE_ID=" + ProfileID.Value : "STORE_ID=" + storeID);
i want to change that query to accept parametrized values like this :
List<SqlParameter> params_list = new List<SqlParameter>();
SqlParameter param_ProfileID = new SqlParameter("#PROFILE_ID", ProfileID);
param_StoreID.SourceColumn = "PROFILE_ID";
param_StoreID.DbType = DbType.Int64;
params_list.Add(param_ProfileID);
but what if Profile_id is null ? how can i do it
Basically, you use DBNull.Value:
SqlParameter param_ProfileID = new SqlParameter("ProfileID",
(object)ProfileID ?? DBNull.Value);
And use #PROFILE_ID in the TSQL, for example:
where table.ProfileID = #ProfileID
Alternatively, use a helper tool like dapper, and forget about it:
return connection.Query<SomeType>(
"select * from SomeTable where ProfileID = #ProfileID",
new { ProfileID }).ToList();
(which returns a List<SomeType>, not a DataTable)
Re conditional searching, there are various approaches here; one is the sub-optimal:
where (#Foo is null or table.Foo = #Foo)
and (#Bar is null or table.Bar = #Bar)
which matches #Foo when it is provided, and #Bar when it is provided - but... it isn't great at hitting indexes, especially if you add more clauses. In your case, I would be tempted to do:
var sql = ProfileID == null
? "select * from Blah where StoreID = #StoreID"
: "select * from Blah where StoreID = #StoreID and ProfileID = #ProfileID";
which uses optimal TSQL for the 2 scenarios. It doesn't matter if you provide unused parameters on the command, but you could also do:
cmd.Parameters.AddWithValue("StoreID", StoreID);
if(ProfileID != null) cmd.Parameters.AddWithValue("ProfileID", ProfileID);
Based upon your comments, the query should look like this:
SELECT * FFROM tbl WHERE (#Profile_Id = NULL AND Store_Id = #Store_Id)
OR (#Profile_Id <> NULL AND Profile_Id = #Profile_Id)
You can set up the parameters like this:
List<SqlParameter> params_list = new List<SqlParameter>();
SqlParameter param_ProfileID = new SqlParameter("#PROFILE_ID", (object)ProfileID ?? DBNull.Value);
param_StoreID.SourceColumn = "PROFILE_ID";
params_list.Add(param_ProfileID);
SqlParameter param_StoreID = new SqlParameter("#STORE_ID", StoreId);
param_StoreID.SourceColumn = "STORE_ID";
params_list.Add(param_StoreID);
you can use this work around
List<SqlParameter> params_list = new List<SqlParameter>();
if(ProfileID==null)
{
SqlParameter param_ProfileID = new SqlParameter("#PROFILE_ID", DBNull.Value);
}
else
{
SqlParameter param_ProfileID = new SqlParameter("#PROFILE_ID", ProfileID);
}
param_StoreID.SourceColumn = "PROFILE_ID";
param_StoreID.DbType = DbType.Int64;
params_list.Add(param_ProfileID);
Looking at your first example, it seems clear that you don't need to build a parameter if your profileID variable is null, simply you write a different query
public static DataTable GetBatches(long storeID, long? ProfileID)
{
List<SqlParameter> pList = new List<SqlParameter>();
string query = "SELECT .... where ";
if(ProfileID.HasValue)
{
query += "PROFILE_ID= #proID";
SqlParameter pProfileID = new SqlParameter("#proID", SqlDbType.BigInt)
.Value = ProfileID.Value;
pList.Add(pProfileID);
}
else
{
query += "STORE_ID= #stoID";
SqlParameter pStoreID = new SqlParameter("#stoID", SqlDbType.BigInt)
.Value = storeID;
pList.Add(pStoreID);
}
If ProfileID is not null you search for it otherwise you search for StoreID and that's all.

The specified argument value for the function is not valid. [ Argument # = 1,Name of function(if known) = isnull ]

I want to select from a table where a column matches a given parameter. If the parameter is null, I want to select all records from the table. The relevant code below is what throws this error.
private static string _dbJobCreate =
"CREATE TABLE Job (jID int primary key identity(1,1), jAddress nvarchar(64) not null);";
private static string _dbJobSelect =
"SELECT jID FROM Job WHERE jAddress = #jAddress OR #jAddress IS NULL";
public static DataTable GetJobs(string jAddress)
{
SqlCeParameter pjAddress = new SqlCeParameter();
pjAddress.ParameterName = "#jAddress";
if (!string.IsNullOrEmpty(jAddress))
{
pjAddress.Value = jAddress;
}
else
{
pjAddress.Value = DBNull.Value;
}
return ExecuteDataTable(_dbJobSelect, pjAddress);
}
Exception: The specified argument value for the function is not valid. [ Argument # = 1,Name of function(if known) = isnull ]
How can I efficiently accomplish this without error in SQLCE?
You can avoid this error by specifying the types of parameters which are passed to the query. So all you need to do is:
pjAddress.DbType = DbType.String;
My solution is to select all rows from the database, and filter down the rows in .NET if a parameter was passed in. This could become troublesome if there were a large number of jobs, although I suppose I'd move to a real database if that ever happens.
private static string _dbJobSelect = "SELECT jID, jAddress FROM Job";
public static DataTable GetJobs(string jAddress)
{
DataTable dt = ExecuteDataTable(_dbJobSelect);
if (!string.IsNullOrEmpty(jAddress))
{
DataView dv = dt.DefaultView;
dv.RowFilter = string.Format("jAddress = '{0}'", jAddress);
dt = dv.ToTable();
}
return dt;
}
You can cast it to varchar
SELECT jID FROM Job WHERE jAddress = #jAddress
OR cast(#jAddress AS varchar(4000)) IS NULL
I ran into this problem recently and discovered that I hadn't actually added the query parameter to the IDbCommand. I'm not sure what your ExecuteDataTable method looks like, but my code was similar to the following (where db is an IDbConnection instance):
var sql = "SELECT jID FROM Job WHERE jAddress = #jAddress OR #jAddress IS NULL";
var cmd = db.CreateCommand();
cmd.CommandText = sql;
var param = cmd.CreateParameter();
param.DbType = DbType.String;
param.ParameterName = "#jAddress";
param.Value = string.IsNullOrEmpty(pjAddress) ? DBNull.Value : (object)pjAddress;
cmd.Parameters.Add(param); // THIS WAS THE STEP I WAS MISSING!!!
// ... rest of the code to execute the query and load the results ...
After adding the cmd.Parameters.Add(param), the exception disappeared.

Categories