I have problem with the parameters in a query in dataset - c#

I have a .NET program with a dataset to an access/a sql DB.
I wrote a query and used 2 parameters, but I got an error:
Error in WHERE clause near '#'.
Unable to parse query text.
My query is:
SELECT DocID, DocCustomerNumber,
DocSessionID, DocTitle, DocKlaser, DocBarcodes
FROM VTblASMCustomersDocsAndGroupCodes
WHERE DocCustomerNumber = #cusNum AND
DocSessionID = #asmNum

Microsoft Access doesn't use named parameters. It uses positional parameters. So the order of the parameters is important when you set the values of the parameters.
Change your query to this:
SELECT DocID, DocCustomerNumber,
DocSessionID, DocTitle, DocKlaser, DocBarcodes
FROM VTblASMCustomersDocsAndGroupCodes
WHERE DocCustomerNumber = ? AND
DocSessionID = ?
Then use this code to pass the parameters:
cmd.Parameters.AddWithValue("param1", param1); // param1 = value of DocCustomerNumber
cmd.Parameters.AddWithValue("param2", param2); // param2 = value of DocSessionID

Related

Stored Procedure With Array parameters csharp to mssql

This is my manual query work in SQL:
SELECT * FROM Accounts where Phone in ('05763671278','05763271578','04763125578')
how can I get parameter like this to stored procedure from csharp?
I have a phones array in C#. I get this array from parameters from a view (multi check box select). This is my view:
<td><input type="checkbox" class="CheckboxClass" value="'#item.Phones'"/></td>
This is my controller action:
public ActionResult SendSMSOrMail(string[] values){
// this give "'05763671278','05763271578','04763125578'"
string numbers = string.Join(",", values);
// ...
utility.cmd.Parameters.Add("#numbers", numbers);
// ...
}
But the result is null. What is wrong? I want to get result of all records which contain these phones.
There are several ways to do this. The first is to create your array as a string of text, separated by commas or semicolons or some other separator, then in the SQL you would parse that string. That's pretty simple and straight forward, but does not scale very well and there is a limit to the max character length of a parameter.
A second choice is to use an XML parameter. Example here:
https://stackoverflow.com/a/1069388/61164
A third choice is to use a Table parameter, which be passed as a .NET collection.
I don't have an example of that handy. I've done it before, but that should give you enough info to search for yourself.
I suggest you use a table valued parameter
CREATE TYPE PhonesTableType AS TABLE
(
Phone VARCHAR(12)
)
GO
Then you should declare (at the creation script) that you stored procedure expects a parameter of this type:
CREATE PROCEDURE dbo.your_stored_procedure_name
(
#PhonesTableType PhonesTableType READONLY
)
....
SELECT A.*
FROM Accounts AS A
INNER JOIN #PhonesTableType AS P
ON A.Phone = P.Phone
Then at the C# code you should create a DataTable with one column and pass there the values you have mentioned. Last you should pass this a parameter to your stored procedure.
var phonesDataTable = new DataTable("Phones");
phonesDataTable.Columns.Add("Phone", typeof(string));
foreach(var phone in phones) // phones is the values
{
phonesDataTable.Rows.Add(phone);
}
Then if we suppose that you have named command the command that you would ask to be executed, before executing it you should add the above as a parameter:
var sqlParameter = new SqlParameter
{
ParameterName = "#PhonesTableType",
SqlDbType = SqlDbType.Structured,
Value = phonesDataTable
};
command.Parameters.Add(sqlParameter);

Passing Parameter to MDX Query through ADOMD in C#

Iam building an webapp. I am attempting to retrieve to pull data from an SSAS cube through MDX query in C#.(from WebAPI).
Can any one please share a sample of code to how to pass a parameter in MDX Query through C#?
This is about the simplest example:
You can wrap a parameter in StrToSet if you need to use a set expression.
var connection = new AdomdConnection(...);
var command = new AdomdCommand(#"
SELECT StrToMember(#Measure) ON 0
FROM [SomeCube]
", connection);
command.Parameters.Add(new AdomdParameter("Measure", "[Measures].[Foo]"));
var cellset = command.ExecuteCellSet();

C# Dapper query using WHERE IN

I am trying to perform a dapper query like this:
string query = "select * from MyTable where someNumber in #Nums;";
...
connection.Query<ReturnObj>(query, new {Nums = nums})
And I am getting a MySql syntax error if nums is empty. It looks like Dapper changes the query to look like this: WHERE 1 = 0) so I am guessing it the left ( is missing, which is causing the syntax error. Yes, I realize I could just check if the collection is empty before executing the query, but I would rather not if I don't have to.
This is a bug in Dapper where it creates a SQL statement that is invalid for MySQL Server 5.6 (and earlier).
Workarounds:
Upgrade to MySQL Server 5.7 (which accepts the SQL Dapper generates and returns the expected results)
As you said, check if the collection is empty before executing the query
A variant of checking if the collection is empty (that can be useful if you have a complex query, NOT IN, etc.):
var numsSql = nums.Any() ? "#Nums" : "(select null)";
var query = $"select * from MyTable where someNumber in {numsSql};";
conn.Query(query, new { Nums });

DataContext ExecuteQuery

string query = #"SELECT ColA, ColXML FROM TableT WHERE ColXML.exist('/SuperNode/Node/SubNode[.=({0})]') = 1";
string param = "''value1'',''value2'',''value3''";
string sQ = string.Format(query, param);
A: dbContext.ExecuteQuery(sQ);
B: dbContext.ExecuteQuery(query, param);
A executes and returns result but B doesn't.
Any reason for this? Also, does the param gets validated for common SQL injection patterns?
Thanks for any pointers!
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.executequery.aspx
You are trying to use the overloaded version of ExecuteQuery that receive parameters. Parameters must be passed as an Object array, for example:
object[] param = new Object[] { "value1", "value2", "value3" };
Anyway, your query receives only ONE parameter:
string query = #"SELECT ColA, ColXML FROM TableT WHERE ColXML.exist('/SuperNode/Node/SubNode[.=({0})]') = 1";
It seems that you want to pass a single parameter composed by three xml values. I am not an XQuery expert but you can try this:
object[] param = new Object[] { "''value1'', ''value2'', ''value3''" };
string query = #"SELECT ColA, ColXML FROM TableT WHERE ColXML.exist('/SuperNode/Node/SubNode[.=({0})]') = 1";
For anyone stumbling upon this via google as I did, ExecuteQuery does not simply pass the command and parameters to string.Format as that would create an injection vulnerability.
It replaces the {0}, {1}, ... in the command with "#p0", "#p1" etc, and then adds your parameters as parameters to the sql command. This can be confirmed by setting the .Log property on the data context to see the command actually executed.
So the OP's example doesn't work because
f(x) where x = "a,b,c"
is only equivalent to
f(a,b,c)
if we're doing a straightforward string substitution. If x is a "proper" SQL parameter then it doesn't work.

C# Run a procedure without specifying a parameter name

How can I execute a stored procedure that takes in parameters without having to specify the prameters name? The name of the parameter in the stored procedure may change from CustomerID to CustID so I don't want to have to keep changing my code.
Rather than doing what is provided below where you specify the parameter name -
command.Parameters.Add("#dtStart", SqlDbType.DateTime);
command.Parameters["#dtStart"].Value = startDate;
command.Parameters.Add("#CustomerID", SqlDbType.NChar);
command.Parameters["#CustomerID"].Value = customerID;
I am looking to do something like this -
command.Parameters.Add(startDate, customerID);
The name of the parameter in the stored procedure may change from CustomerID to CustID
Slap the person who does that.
Parameter names are your reliable way of identifying a parameter. The other option is sequence, seems a lot more flaky.
I don't think you can create a SqlParameter object without specifying its name. However, you should be able to use the DeriveParameters method (see MSDN) to get a collection of parameters with the names automatically retreived from the SQL server.
You can find an example here. It looks roughly like this:
SqlCommand command = // create a command for calling the stored procedure
SqlCommandBuilder.DeriveParameters(command);
// Now you can set values of parameters in a loop
for(int i = 0; i < command.Parameters.Length; i++) {
var parameter = command.Parameters[i]
// Set value of ith parameter
}
You can create a nameless SQL parameter if you force its name to null or empty after it's been added to the Parameters collection, something like this:
var par = cmd.CreateParameter();
par.Value = myValue;
cmd.Parameters.Add(par); // this will change the name to "ParameterX"
par.ParameterName = null;
Use Parameter Discovery, scroll down on: http://msdn.microsoft.com/en-us/library/ff664692(PandP.50).aspx
Using Unnamed parameters is only possible with OdbcCommand and OleDbCommand object parameters.
You could use SQL's exec, which does not ask for parameter names:
command.CommandText = string.Format(
"exec dbo.YourProcedure {0}, '{1}'",
intParameter,
stringParameter.Replace("'","''")
);
command.ExecuteNonQuery();
If your parameter source is untrustworthy, be sure to escape single quotes in string parameters. It's done for stringParameter in the snippet above.

Categories

Resources