I'm attempting to pass a string of numbers into a query that will run against our AS400 connection however it doesn't seem that my value is actually making it to the query. I am returning a result when I debug to the point of the parameter so I know I'm getting my number.
var command = new OleDbCommand("SELECT UMACT, UMCUS, UMNAM, UMAD1, UMAD2, UMAD3, UMZIP, UMOPH, UMSLC FROM CFFILES.UMST WHERE trim(UMEMT) = '?' ", connection);
//Test meter number: 59115796
connection.Open();
OleDbParameterCollection paramCollection = command.Parameters;
paramCollection.Add(meternumber.ToString(), OleDbType.LongVarChar);
When I pass a number directly into the query it returns a perfect result however when I try to pass a number from the parameter it returns null.
Here is the variable itself that I know is being passed to my parameter that I created above because I get a result when I debug to that line.
public IEnumerable<CustomerInfoModel> GetCustomerInfo()
{
int meternumber = 59115796;
getAS400Data(meternumber);
return customerList;
}
For my AS400 query to work I have to have the ticks around the ? in the query so I'm not sure if that is perhaps causing the issue.
You have the call to Add method wrong. The first parameter of Add is the Name of the parameter, the second is the DataType and finally you should set the value of the parameter in this way
OleDbParameterCollection paramCollection = command.Parameters;
paramCollection.Add("whatever", OleDbType.LongVarChar).Value = meternumber.ToString();
See OleDbParameterCollection.Add
And no, you shouldn't add ticks around the question mark placeholder. If you do you transform your placeholder in a literal string and obviously you don't have any row with a question mark as value.
A final note, in OleDb parameters doesn't have a name, but when you add them to your collection you should provide one so you are free to choose whatever you like for the name. Just remember to keep them in the same order in which the placeholders (?) appears in your query string
Related
I have in my class "fattura" this
public string sommaFattura(String costo)
{
MySqlCommand command = new MySqlCommand();
String sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
command.CommandText = sumQuery;
command.Connection = conn.getConnection();
command.Parameters.Add("#prezzo", MySqlDbType.Int32).Value = costo;
conn.openConnection();
//Need the command for take the result
conn.closeConnection();
}
What is the command for take the result of Sum query?
I want use this command, insert in a variable. Can you correct me?
I think the command you want is
command.ExecuteScalar();
However, note, Execute Scalar is intended that the result will return a single row, single column which your query does without regard to your parameter. However your query does not specifically make sense either..
Now your query itself. You have an explicit prezzo which would imply an existing column name and not that of a parameter. It would have to a numeric field for obvious reasons to sum it.
Now you also have an expected string coming in via "costo" parameter to the function call. If your intent is to have the incoming string be representative of a known column of the table, this is not going to work for you. You would have to build the SQL command with that explicit column name, or build doing dynamic-sql, but that would really be too much.
The concern with building a SQL statement with string parameters is you would be open to SQL-injection, especially if web-based. If your incoming string is coming from a controlled source, such as you are presenting a list of columns to a user and they can only pick one such column. Or, you have buttons on a screen asking for a sum of a certain thing, and YOU control that column name you would be in a better condition, but still be cautious passing parameter to build out SQL.
Say for example your table has numeric fields of qtySold and dollarSales. You want either the sum of either of these columns and are passing one of these respective strings into the function such as
var qtySoldAnswer = sommaFattura( "qtySold" );
or
var dollarSalesAnswer = sommaFattura( "dollarSales" );
Then your function would be CLOSER to...
public string sommaFattura(String costo)
{
MySqlCommand command = new MySqlCommand();
command.CommandText = "SELECT SUM(" + costo + ") FROM fatturetemp";
command.Connection = conn.getConnection();
conn.openConnection();
var answer = command.ExecuteScalar();
conn.closeConnection();
// I would put a breakpoint in here to see the results.
// you can then format the answer such as decimal point, etc.
return answer.ToString();
}
AGAIN, ONLY if YOU have control of the column name you are trying to send in. Someone could do sql-injection and do a lot of damage. I would only do with heavily controlled consideration and explicitly validating the columns you WOULD allow, and if so, set your variable at that point. Don't allow for any more or less than the column name. No special characters, quotes, comments, sql-terminator and new statement...
But hopefully this clarifies what I THINK you are trying to accomplish.
I'm having a problem where I don't know how I'm supposed to pass in an Oracle parameter where the C# type is a string and the Oracle type is a Varchar2.
Currently I'm passing in this string as CMS','ABC thinking that Oracle will add in the '' that surround this string making it a varchar2 that looks like 'CMS','ABC'.
This works for a single string like CMS but when the value is something longer, like something typically in a IN (list) command the parameter won't be passed in correctly.
This is the code I'm referring too.
string sql = 'SELECT name FROM Pers p WHERE p.FirstName IN (:names)';
The below works when the value of :names being passed in is CML without any quotes.
OracleParameter param = new OracleParameter(":names", OracleDbType.Varchar2, "CML", ParameterDirection.Input);
Below doesn't work when the value of :names being passed in is CML','ABC with quotes on the inside.
OracleParameter param = new OracleParameter(":names", OracleDbType.Varchar2, "CML','ABC", ParameterDirection.Input);
Why is that?
Does Oracle add in single quotes around the parameter when it's passed into the sql statement? Why doesn't it add quotes around the second case?
ODP.NET parameters do not work with multiple, comma separated values. Each parameter is treated as a single value, whatever kind of quotes it contains.
Oracle does not add quotes around parameter values when passed to a query. Quotes are just a way to write a VARCHAR value in a query, but when using parameters, Oracle doesn't "replace your parameter with its value then execute the query", as this would allow SQL injection.
If that was the case, imagine your parameter value was: "CML', 'ABC');DROP DATABASE Test;--". Oracle would then execute SELECT name FROM Pers p WHERE p.FirstName IN ('CML', 'ABC');DROP DATABASE Test;--'!
See this question for ideas on how to solve your problem: Oracle Parameters with IN statement?
From your comments/answers I was able to come up with this solution. I hope it helps others who come.
To get around ODT.NET parameters not working with multiple comma separated values you can divide each value into its own parameter. Like the following.
string allParams = "CML, ABC, DEF";
string formattedParams = allParams.Replace(" ", string.Empty); // Or a custom format
string [] splitParams = formattedParams.Split(',');
List<OracleParamter> parameters = new List<OracleParameter>();
string sql = #"SELECT * FROM FooTable WHERE FooValue IN (";
for(int i = 0; i < splitParams.Length; i++)
{
sql += #":FooParam" + i + ",";
parameters.Add(new OracleParameter(":FooParam" + i, OracleDbType.Varchar2, splitParams[i], ParameterDirection.Input));
{
sql = sql.Substring(0, (sql.Length - 1));
sql += ')';
The string sql will now have this as it's value: SELECT * FROM FooTable WHERE FooValue IN (:FooParam0,:fooParam1, etc...)
This will solve the problem.
Another approach would be to add in a bunch of OR clauses for each parameter. The above example is better since you don't write a bunch of OR clauses though.
I am executing a SQL Server stored procedure from my C# code which essentially pulls some data from a database based on the supplied condition.
DataSet GetAllxxxxxByDate(string entityValue,string companyValue)
{
using (var sqlConn = new SqlConnection(GetConnectionString()))
{
using (var cmd = new SqlCommand())
{
var data = new DataSet();
cmd.CommandText = “myStoredprodecure”;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConn;
var eVal = string.IsNullOrWhiteSpace(entityValue) ? string.Empty : entityValue;
cmd.Parameters.AddWithValue("#entity_value", eVal);
var company = string.IsNullOrWhiteSpace(companyValue) ? string.Empty : companyValue;
cmd.Parameters.AddWithValue("#company", company);
var sqlDataAdaptor = new SqlDataAdapter(cmd);
sqlDataAdaptor.Fill(data);
return data;
}
}
}
Here entityValue, companyValue are comma separated strings, formed dynamically within C# code and pass it to stored procedure.
Eg:
’first’,’second’,’third’
And the stored procedure uses these values to fill the NOT IN condition defined within it.
The issue is that, I am getting inconsistent number of records when I execute the code.
Following is a quick screenshot where first WHERE clause return 3 records and second WHERE clause return 1 record. The input values for the first WHERE clause is been filled from c# code and the second is been filled manually to test.
The only difference, which I can spot is number of quotes.
Question: can someone help me to zero in the issue or the difference in these give WHERE clause ?
Well, you don't show what entity_value is in your results, but the difference between the two is you're adding single quotes around the literal values:
N'''FSEC''' in SQL is the literal valiue 'FSEC'
'FSEC' in SQL is just FSEC (without the quotes).
My guess is that records 2004981 and 2004982 have a value of FSEC (without the quotes) for entity_value.
If you're adding parameter values from C# code, don't add quotes around them like you would if you were building a string. SQL will treat the values as strings without needing string qualifiers.
EDIT
Okay, I just read this statement:
Here entityValue, companyValue are comma separated string
You can't just pass in a comma-delimited string to an IN clause. To search for multiple values there are a few options:
Add commas to each end and use LIKE:
Where (',' + #entity_value +',' LIKE '%,' + entity_value + ',%')
Parse the string into a temporary table, than use that table in your IN clause
Pass the values as a table-valued parameter and use that in your IN clause.
Build the SQL statement as a string and execute it with EXEC
When I try to insert a string value using mdmysql.Parameters.AddWithValue it generates an input format string exception. Following is the code which produces the error:
cmdmysql.Parameters.AddWithValue("#p_mode", MySqlDbType.VarChar).Value = "ccc";
I tried with varchar, string, text but nothing is working. Also if I put null in place of "ccc" then the record gets inserted into the table. The variable type for p_mode in table is varchar. What is the reason for this exception?
The AddWithValue function takes only two inputs, 1. The parametername and 2. the value
cmdmysql.Parameters.AddWithValue("#p_mode", "ccc");
If you want to use the definition of types you must use the normal Add function:
cmdmysql.Parameters.Add("#p_mode", MySqlDbType.VarChar).Value = "ccc";
I would guess that the exception comes from your second input where you parse an MySqlDbType to the function and not the acutal value you want the returned mysqlparameter to have.
Try this
cmdmysql.Parameters.AddWithValue("#p_mode","ccc");
I'm getting ora-01475 whenever I try to insert a null value in a column (of type DateTime) after some records have already been inserted that have real date values.
I'm using the OracleParameter constructor that takes the name and the value as an object (I assume the data type is then implied from the datatype of the object), but since sometimes the value of my parameter is null, it's being set as a String, therefore throwing this error.
I don't want to use the constructor that takes the datatype explicitly because I use reflection heavily to build the OracleCommand object and its parameters.
How can I reparse the cursor (as the error suggests) if I find this situation?
Has anyone else run into this and has a solution?
Have you tried to use nullable types?
DateTime? myDate;
//Code to set myDate value...
string sql = "[your SQL]"
using (OracleCommand command = new SqlCommand(sql, cn))
{
OracleParameter param = new OracleParameter(":Name",myDate);
command.Paerameters.add(param);
command.ExecuteNonQuery();
}