Select column values not existing in string array [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm writing a code in Asp.net c# to select some values from SQL Server database.
I want to get all the values in a table that does not contain the items of a string array.
In detail, I have a table named Notifications which contains 2 columns, 'Text' and 'Date'. I also have a string array.
I want to get all the Texts and dates that do not exist in my string array
Thank U all

You'll first need to convert your array of strings into a comma-separated list that can be passed into your query. Then have your query filter our any records where the value of the Text column is in that list:
public string GetNotifications(string[] texts)
{
// Create a single string with all values from the texts array.
// Ex: 'value1','value2','value3'
// There are many ways to do this; here's one way using string.Join and LINQ:
var textsAsSingleString = string.Join(",", texts
.Select(x => "'" + x.Replace("'", "''") + "'")
.ToArray());
// Create your query with a WHERE clause that checks against your list
var query = "SELECT Text, Date " +
"FROM Notifications " +
"WHERE Text NOT IN (" + textsAsSingleString + ")";
// Execute the query
SqlCommand cmd = new SqlCommand(query, con);
...
}
Now, this should work fine with a few values in the texts array, but if that array gets very large (how large depends on many environmental factors), the performance could start to degrade. However, unless you tell me otherwise, I'll assume the list isn't very long.
Edit: If any string in texts contains a single quote, this will fail. You need to replace any single single quote with two single quotes. I've updated the sample above to do this by calling Replace("'", "''") on each string in texts before adding it to the comma-separated list/string.

I am not sure what way you are connecting to DB but you can always use this:
If using Linq:
string sParms = String.Join(",", saParams.Select(str => "'" + str + "'").ToArray());
and then you can use sParms in your where clause.
If not using Linq:
string[] saParams = new string[3] { "String1", "String2", "String3" };
StringBuilder sbParams = new StringBuilder();
foreach(string sStr in saParams)
{
if (sbParams.Length > 0)
sbParams.Append(",");
sbParams.Append("'" + sStr + "'");
}
and then you can use sbParams.ToString() in your where clause.

Related

C# Extension method to Convert into the comma separated [duplicate]

This question already has answers here:
IN Operator in OLEDB
(2 answers)
Closed 1 year ago.
I have some data like name,firstname,surname,std,Rollno.
Using C#, I want to convert this into
('name', 'surname', 'std', 'Rollno')
so that I can use this this data to query into the SQL/MySQL DB like -
SELECT *
FROM Table1
WHERE UserCommunicationId IN ('name', 'surname', 'std', 'Rollno');
Instead of
SELECT *
FROM Table1
WHERE UserCommunicationId IN ('name,surname,std,Rollno');
You can try below below logic
public static class SQLQueryExtensions
{
public static string ColumnFormat(this String str)
{
return "(" + //Include first parenthesis
string.Join(", ", str.Split().Select(x => $"'{x}'")) //Add single quote to each column
+ ")"; //Include last parenthesis
}
}
You can do it in one line as well,
var inputStr = "name,firstname,surname,std,Rollno";
var result = "(" + string.Join(", ", inputStr.Split().Select(x => $"'{x}'")) + ")";
Try Online
Use blow logic, will solve your problem.
string inputStr = "name,firstname,surname,std,Rollno";
string result = string.Join(",", inputStr.Split(',').Select(x => string.Format("'{0}'", x)).ToList());
Output = 'name','firstname','surname','std','Rollno'
One approach I can come up is that:
Set the whole string into query as a parameter.
Split it in a WITH query.
LEFT JOIN it in the main query.
NOT NULL to check if there's any hit.
I've wrote an example below, but I am Oracle user so I am not sure if these syntax are right, not even tested, just googled around. Only take it as an reference to the explanation of the idea.
WITH RECURSIVE targets (stringBuffer, word) AS (
SELECT
#Parameter
,NULL
UNION ALL
SELECT
SUBSTRING(stringBuffer, LEAST(LENGTH(SUBSTRING_INDEX(stringBuffer, ',', 1) + 1, LENGTH(stringBuffer)))
,SUBSTRING_INDEX(stringBuffer, ',', 1)
WHERE LENGTH(word) > 0
OR LENGTH(stringBuffer) > 0 -- I am not really sure about these
)
SELECT *
FROM Table1
LEFT JOIN targets ON targets.word = Table1.UserCommunicationId
WHERE targets.word IS NOT NULL;
Then, in C#, set Parameter for your query command in string like this
string s = "name,firstname,surname,std,Rollno";
Edit:
Or, simply:
SELECT *
FROM Table1
WHERE REGEXP_LIKE(UserCommunicationId, #Parameter)
;
While setting the Parameter in C# as:
string s = "name|firstname|surname|std|Rollno";
Notice that if the keywords can be input by user, you still have the problem where user may enter .+ and it responds every data to them as long as there's no other condition added.
But personally, I think there's a potential issue in your design if you really need an unknown length of IN-CLAUSE in your query. If keywords that can be applied are limited in number, you can, rough but it's my team's current criteria, concat the WHERE section keyword by keyword in C#.

MySQL Query Returns Parameter Column Name [duplicate]

This question already has answers here:
How to pass a table as parameter to MySqlCommand?
(2 answers)
Closed 6 years ago.
I am working in C# and MySQl in VS2015 to query my database and return a the information in a VARCHAR type column titled "method". However, the query returns the string "method", and not the values of the method column.
below is the code:
string queryOne = "SELECT " + "#columnName" + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
cmdOne.Parameters.AddWithValue("#columnName", "method");
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne.GetString(0));
}
dataReaderOne.Close();
While this is the output:
method
method
method
.
.
.
.. for the number of rows in the method column. Is this a formatting problem? Is it possible that the configuration of my database is preventing VarChar's from returning correctly? When I change the query to query a column of type INT, it returns the correct values for an INT type column.
You can't parameterize a column name in a select statment. What you're doing is exaclty like saying select 'foo' from log.transactions. It selects the string 'foo' once for each row. You're just sticking a string value in there; it's not parsing the string value as SQL.
What you can do (if you can afford it) is select * from log.transactions, then your C# code can grab the data in whatever column the caller passed you the name of. With a lot of rows you could be dragging a lot of useless junk back from the DB though.
What you want in the code you show, though is just this:
string queryOne = "SELECT method FROM log.transactions";
If you really want to parameterize "method", that's sketchy because of SQL injection vulnerabilities.
string queryOne = "SELECT " + fieldname + " FROM log.transactions";
That looks good until some comedian using your application gives you a value of "0; drop table log.transactions;--" in the textbox. Then you've got troubles. If you ever concatenate a string variable into a SQL string that you're going to execute, you've got to be fanatical about sanitizing it, and even then you want to avoid it any way you can. It's Russian roulette.
Your query formation has to be like if you want to keep your column dynamic.Now pass column name accordingly.
string queryOne = "SELECT " + column_name + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne[column_name]);
}
dataReaderOne.Close();

How to get fields from database [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to get "Model" field and put on Textbox6. But how come it does not work.
The problem is that the Model field answer will not be shown in the textbox6
string Query = "Select * from S where Name = '" + TextBox1.Text + "' and Clientno = '" + TextBox2.Text + "';";
command.CommandText = Query;
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
string Model = reader.GetString(reader.GetOrdinal("Model"));
TextBox6.Text = Model;
}
Couple of things:
Do not use select *, instead use select your columns names
Do not pass the .Text directly to your query, instead use parameterized sql expression
If Clientno is primary key column or , combination of Name and ClientNo gives unique result, use ExecuteScalar, you don't have to use ExecuteReader and loop through the datareader
Since you using only one field and want to fill in the textbox, modify your select statement to :
select top 1 Model from S where....
And if you are reading only one row you will not need a while loop. Further, you should always close the reader and put your SqlConnection inside using block. ( edited as suggested by the comments)
If (reader.Read())
{
TextBox6.Text = reader.GetString(reader.GetOrdinal("Model"));
reader.Close();
}

Adding a list of strings to OracleCommand.Parameters in C# [duplicate]

This question already has answers here:
problem using Oracle parameters in SELECT IN
(3 answers)
Closed 10 years ago.
The following query has a parameter to be assigned with a list of strings:
select * from a_table where something in :list_of_strings
I have a C# List<string> which I would like to assign to the list_of_strings parameter.
Given an OracleCommand (representing the above query), how can I bind my List<string> to the command's list_of_strings parameter?
Actually, you can't bind a single parameter to a list of values. In this case you could concatenate the values to the query string.
However, that's unadvised since there's a limit of values you can put on an IN clause.
List<string> list = new List<string>();
list.Add("1");
list.Add("2");
list.Add("3");
list.Add("4");
string listStr = string.Join(",", list);
//result: "1,2,3,4"
If your string list is a list of strings, you could do this:
List<string> list = new List<string>();
list.Add("one");
list.Add("two");
list.Add("three");
list.Add("four");
string listStr = string.Concat("'", string.Join("','", list), "'");
//result: "'one','two','three','four'"
Query string:
string query = string.Format("select * from a_table where something in({0})", listStr);
Obs: you may have to handle the possibility where the list is empty.
Another possibility would be inserting all the values on a temporary table and using it on the select statement. Which would have the advantage of unlimited string values and avoiding a new hard parse on the DBMS compared to the concatenating technique:
SELECT *
FROM A_TABLE
WHERE SOMETHING IN(SELECT SOMETHING FROM TEMP_TABLE)

Appending a list of integers to your SQL Server query in c#. How can I do this?

Here is a broken down version of my problem :
I have a method. The argument is a list of integers. I wish to create an optimised SQL query that returns a particular value on all rows where the id of that row is equal to one of the integers in the argument list. Simple, right ?
I have a feeling I have made it more difficult than it needs to be :
private List<string> ReturnValue(List<int> ids)
{
List<string> ValuesIWantToReturn = new List<string>();
StringBuilder sb = new StringBuilder("SELECT ValueIWantToReturnfrom table WHERE ");
foreach (int id in ids)
{
sb.Append( string.Format("ID = {0} OR ", id) );
}
sb.Remove(sb.Length - 3, 3); //remove trailing "OR"
sb.Append(";");
SqlDataReader reader = RunSelectQuery( sb.ToString() );
while (reader.Read())
{
ValuesIWantToReturn.Add(reader.GetString(0));
}
return ValuesIWantToReturn;
}
Any feedback on the general readability and structure of my code would be appreciated too. It's always nice to improve :)
You can use the IN syntax rather than OR
WHERE id IN (1,2,3,4)
It may be more efficient to pass the list of IDs as a table valued parameter to a stored procedure, and then join that to your table, but that may be over engineering the solution - depending on how long your list of numbers is.
Instead of your loop, you can use string.Join to build your list
string query = "SELECT ValueIWantToReturn from table WHERE ID IN ("
+ string.Join(",", ids)
+ ")";
(assuming that there is always at least one number in the list)

Categories

Resources