Add parameter issue for fulltext search in C# - c#

I have this part of code
string query = "SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,#text)";
sqlCommand.CommandText = sql;
sqlCommand.Parameters.Add("#text", value+"*");
value is a function parameter.
For fulltext search, the sql statement must be like this:
SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,'"eng*"')
It could search strings which start with "eng" -> english, bla blah.
But executing in C# the above code then ExecuteReader() returns empty list.
#text has as value "sometext*" but I want to add ' ' characters.
I tried string query = "SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,'#text')";
but it doesn't work, returns empty list.
Why ? How do I proceed that #text parameters must include '' characters over value for search ?
Thank you

Can you try using sqlCommand.Parameters.AddWithValue("#text", value+"*");
If above doesn't work, you can use SQL Parameter and SqlDBType.
I think your SQL query is wrong. See is this post helps.
C# constructing parameter query SQL - LIKE %

Have you tried specifying the data type? I don't think you should need the quotes in the sqlcommand string.
sqlCommand.Parameters.Add("#text", SqlDbType.VarChar);
sqlCommand.Parameters["#text"].Value = value+"*";
Or SqlDbType.NVarChar.

Related

Passing in Oracle Parameter to SQL string

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.

C# Select Query Failed with no errors

I'm having trouble with a simple SELECT query, I cannot see why it isn't working.
Here is the code:
conn.Open();
string GetPayrollQuery = "SELECT PayrollNo FROM [Employee] WHERE (FirstName + ' ' + LastName) = #Name";
OleDbCommand GetPayroll = new OleDbCommand(GetPayrollQuery, conn);
GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text;
var GotPayroll = GetPayroll.ExecuteNonQuery();
MessageBox.Show(GotPayroll.ToString());
return Convert.ToInt32(GotPayroll);
The code runs fine however it isn't extracting the data. Can anyone see why this would be?
I bet #name is coming as "MikeSmith" instead of "Mike Smith".
3 things:
try to open SQL profiler and check what you are executing on database
check database collation, is it case sensitive?
remove executenonquery (it's must used with update, delete, not select) and try executescalar (if one result for one row is exptected, otherwise try to fill a datatable or use datareader)
Make sure the same query runs in SQL using those parameter values.
Change GetPayroll.ExecuteNonQuery() to GetPayroll.ExecuteScalar() so to return a single result.
Change GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text; to GetPayroll.Parameters.AddWithValue("#Name", cbbEmployees.Text);
Use cbbEmployees.SelectedText. Fixes the problem.

statement for npgsql using parameter

I pass the parameters in the sql query using the driver npgsql:
SqlCommand = new NpgsqlCommand();
....
SqlCommand.CommandText = "SELECT id,name FROM table1 WHERE field1=:param2 ORDER BY name;";
SqlCommand.Parameters.AddWithValue("param2", 1);
This query executed correctly and issued the necessary data, but as soon as I add parameter to the sql in the section "select"
SqlCommand.CommandText = "SELECT id,name :param1 FROM table1 WHERE field1=:param2 ORDER BY name;";
SqlCommand.Parameters.AddWithValue("param1", ",field1");
SqlCommand.Parameters.AddWithValue("param2", 1);
it gives me some kind of nonsense. In theory this request to the server is to be treated as
SELECT id,name,field1 FROM table1 WHERE field1=1 ORDER BY name;
but it did not happen.
This raises the question: is there a way to dynamically insert a list of fields using suchlike parameters?
Unfortunately, Npgsql doesn't have support for what you are trying to do. NpgsqlParameter values are supposed to be only used as parameter values in the where clause.
In order to add field names dynamically as you intend, you will have to create the query manually by using string concatenation.
I hope it helps.
Rewrite you CommandText and add this:
foreach (NpgsqlParameter item in _Command.Parameters)
{
comm.Parameters.AddWithValue(item.ParameterName, item.Value);
}
And solve your problem..

how to add ' like special characters in mysql varchar data type column?

I am trying to insert string as "baby's world" into the column of type varchar through query but shows me error.
Is there anything else i need to put to the query so that it accept that symbol
put a backslash in front of it like so:
"Baby\'s world"
You can find and replace them in your string using the following:
str.Replace('\'', '\\\'')
I'm not 100% sure about this last part, but you need to 'escape' the ' and \ by adding a \ in front of it. So it would seem alright (can't test as i'm not a C# programmer.
Since you are asking about Visual Studio (.NET), you need to use parameterized query. Don't use concatenation when constructing query
private void PrepareExample()
{
string s = Console.ReadLine();
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
cmd.Parameters.AddWithValue( "?title", "baby's world" );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Or
private void PrepareExample()
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
// try to input: baby's world. or try: baby"s world. everything are ok :-)
cmd.Parameters.AddWithValue( "?title", Console.ReadLine() );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Though this is not exactly concatenation, don't use this:
qry = string.Format("INSERT INTO movie(title) VALUES("{0}", Console.ReadLine());
Though if you really found a need to run SQL that way, replace single quote with backslash
qry = string.Format("INSERT INTO movie(title) VALUES("{0}",
Console.ReadLine().Replace("'", "\'");
But do consider using parameterized query instead of concatenation or string.Format, as parameterized query automatically take care of those delimeter nuances.
http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html
Just use mysql_real_escape_string(). There is no need to do anything else.
For example:
mysql_real_escape_string($user),
mysql_real_escape_string($password));
INSERT INTO table (field) VALUES ('baby's world') will fail because the string is truncated to INSERT INTO table (field) VALUES ('baby' and the rest is seen as invalid code.
There are two ways to stop this, the second being advisable for good practice coding:
INSERT INTO table (field) VALUES ("baby's world")
INSERT INTO table (field) VAUES ('baby\'s world')

String list in SqlCommand through Parameters in C#

Working with a SqlCommand in C# I've created a query that contains a IN (list...) part in the where clause. Instead of looping through my string list generating the list I need for the query (dangerous if you think in sqlInjection). I thought that I could create a parameter like:
SELECT blahblahblah WHERE blahblahblah IN #LISTOFWORDS
Then in the code I try to add a parameter like this:
DataTable dt = new DataTable();
dt.Columns.Add("word", typeof(string));
foreach (String word in listOfWords)
{
dt.Rows.Add(word);
}
comm.Parameters.Add("LISTOFWORDS", System.Data.SqlDbType.Structured).Value = dt;
But this doesn't work.
Questions:
Am I trying something impossible?
Did I took the wrong approach?
Do I have mistakes in this approach?
Thanks for your time :)
What you are trying to do is possible but not using your current approach. This is a very common problem with all possible solutions prior to SQL Server 2008 having trade offs related to performance, security and memory usage.
This link shows some approaches for SQL Server 2000/2005
SQL Server 2008 supports passing a table value parameter.
I hope this helps.
You want to think about where that list comes from. Generally that information is in the database somewhere. For example, instead of this:
SELECT * FROM [Table] WHERE ID IN (1,2,3)
You could use a subquery like this:
SELECT * FROM [Table] WHERE ID IN ( SELECT TableID FROM [OtherTable] WHERE OtherTableID= #OtherTableID )
If I understand right, you're trying to pass a list as a SQL parameter.
Some folks have attempted this before with limited success:
Passing Arrays to Stored Procedures
Arrays and Lists in SQL 2005
Passing Array of Values to SQL Server without String Manipulation
Using MS SQL 2005's XML capabilities to pass a list of values to a command
Am I trying something impossible?
No, it isn't impossible.
Did I took the wrong approach?
Your approach is not working (at least in .net 2)
Do I have mistakes in this approach?
I would try "Joel Coehoorn" solution (2nd answers) if it is possible.
Otherwise, another option is to send a "string" parameter with all values delimited by an separator. Write a dynamic query (build it based on values from string) and execute it using "exec".
Another solution will be o build the query directly from code. Somthing like this:
StringBuilder sb = new StringBuilder();
for (int i=0; i< listOfWords.Count; i++)
{
sb.AppendFormat("p{0},",i);
comm.Parameters.AddWithValue("p"+i.ToString(), listOfWords[i]);
}
comm.CommandText = string.Format(""SELECT blahblahblah WHERE blahblahblah IN ({0})",
sb.ToString().TrimEnd(','));
The command should look like:
SELECT blah WHERE blah IN (p0,p1,p2,p3...)...p0='aaa',p1='bbb'
In MsSql2005, "IN" is working only with 256 values.
I would recommend setting the parameter as a comma delimited string of values and use a Split function in SQL to turn that into a single column table of values and then you can use the IN feature.
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648 - Split Functions
If you want to pass the list as a string in a parameter, you could just build the query dynamically.
DECLARE #query varchar(500)
SET #query = 'SELECT blah blah WHERE blahblah in (' + #list + ')'
EXECUTE(#query)
I used to have the same problem, I think there is now way to do this directly over the ADO.NET API.
You might consider inserting the words into a temptable (plus a queryid or something) and then refering to that temptable from the query. Or dynamically creating the query string and avoid sql injection by other measures (e.g. regex checks).
This is an old question but I've come up with an elegant solution for this that I love to reuse and I think everyone else will find it useful.
First of all you need to create a FUNCTION in SqlServer that takes a delimited input and returns a table with the items split into records.
Here is the following code for this:
ALTER FUNCTION [dbo].[Split]
(
#RowData nvarchar(max),
#SplitOn nvarchar(5) = ','
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Data nvarchar(100)
)
AS
BEGIN
Declare #Cnt int
Set #Cnt = 1
While (Charindex(#SplitOn,#RowData)>0)
Begin
Insert Into #RtnValue (data)
Select
Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
Set #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
Set #Cnt = #Cnt + 1
End
Insert Into #RtnValue (data)
Select Data = ltrim(rtrim(#RowData))
Return
END
You can now do something like this:
Select Id, Data from dbo.Split('123,234,345,456',',')
And fear not, this can't be susceptible to Sql injection attacks.
Next write a stored procedure that takes your comma delimited data and then you can write a sql statement that uses this Split function:
CREATE PROCEDURE [dbo].[findDuplicates]
#ids nvarchar(max)
as
begin
select ID
from SomeTable with (nolock)
where ID in (select Data from dbo.Split(#ids,','))
end
Now you can write a C# wrapper around it:
public void SomeFunction(List<int> ids)
{
var idsAsDelimitedString = string.Join(",", ids.Select(id => id.ToString()).ToArray());
// ... or however you make your connection
var con = GetConnection();
try
{
con.Open();
var cmd = new SqlCommand("findDuplicates", con);
cmd.Parameters.Add(new SqlParameter("#ids", idsAsDelimitedString));
var reader = cmd.ExecuteReader();
// .... do something here.
}
catch (Exception)
{
// catch an exception?
}
finally
{
con.Close();
}
}

Categories