Currently I have a sql call returning a dataset from a MSSQL database and I want to take a column from that data and return ID's based off that column from the ORACLE database. I can do this one at a time but that requires multiple calls, I am wondering if this can be done with one call.
String sql=String.Format(#"Select DIST_NO
FROM DISTRICT
WHERE DIST_DESC = '{0}'", row.Table.Rows[0]["Op_Centre"].ToString());
Above is the string I am using to return one ID at a time. I know the {0} can be used to format your value into the string and maybe there is a way to do that with a datatable.
Also to use multiple values in the where clause it would be:
String sql=String.Format(#"Select DIST_NO
FROM DISTRICT
WHERE DIST_DESC in ('{0}')", row.Table.Rows[0] ["Op_Centre"].ToString());
Although I realize all of this can be done I am wondering if theres an easy way to add it all to the sql string in one call.
As I am writing this I am realizing I could break the string into sections then just add every row value to the SQL string within the "WHERE DIST_DESC IN (" clause...
I am still curious to see if there is another way though, and because someone else may come across this problem I will post a solution if I develop one.
Thanks in advance.
The most RDBMS-agnostic approach you could do is to create a temporary table. Then just query: select * from district where dist_desc in (select dist_desc from temp_table)
There's a solution here in Oracle http://forums.oracle.com/forums/thread.jspa?threadID=930372 , but I don't have Oracle in my box, so I can't try how it will work in .NET.
Have tried this in Postgresql http://fxjr.blogspot.com/2009/05/npgsql-tips-using-in-queries-with.html , have very seamless support for comparing value to list
If you will go the dynamic query approach, try this:
String sql=String.Format(#"Select DIST_NO
FROM DISTRICT
WHERE DIST_DESC IN ({0})",
string.Join( ",",
ds.Tables[0].Select()
.Select(r => "'" + (string)r["Op_Centre"] + "'").ToArray() ) // string.Join
); // string.Format
K I understand its pointless to ask a question and then answer it yourself but by asking the question I realized the answer.
String sql = "Select DIST_NO FROM DISTRICT WHERE DIST_DESC in ('" +ds.Tables[0].Rows[0]["Op_Centre"].ToString()+"'";
for (int i = 1; i < ds.Tables[0].Rows.Count;i++ )
{
sql +=",'"+ds.Tables[0].Rows[i]["Op_Centre"].ToString()+"'";
}
sql += ")";
I am still curious to see if there is a better way though...
Related
Fairly new to SQL. Say I have a table with field1 of type string (VARCHAR) and field2 of type integer (INTEGER). As I understand it, you're supposed to use ='newValue' for string fields, and =newValue for integer fields (and =#newValue# for date fields).
Is there a trick that allows generic construction of the SET clause without needing to know the type of the field being updated in advance?
void UpdateDatabase(string field, string oldValue, string newValue)
{
// Construct without needing work out whether '', ## or (nothing) is required?
string sqlUpdate = (
"UPDATE MyTable" +
" SET " + field + " = " + newValue +
" WHERE " + field + " = " + oldValue);
// Execute the statement on the database
}
This might be used as follows:
UpdateDatabase("field1", "Danger Mouse!", "Mickey Mouse");
UpdateDatabase("field2", "15", "7");
Your code will need to be a lot more complex if you want to predetermine the datatypes of the fields you're inserting into.
Most SQL flavours have some kind of catalog, so for example on MS SQL Server you would need do something like:
SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME = 'field'
For every column you're about to write to, then apply the single-quote or not as per the data type.
There's ways and means of doing this, and depending on how many different fields you want to write at the same time will depend how complex the logic has to be to get the column datatypes.
For a large number of columns ideally you would gather all the column names you're about to write to into a table first, then use that table to query the datatypes
However, in SQL Server you can normally get away with putting single-quotes around everything, even integers and floats. SQL Server will intelligently remove the single quotes as needed.
It looks like you're using MySQL since you're required to put hashes around dates, in which case I am sorry for your loss.
I am having problem updating my database with stock. I want to add stock to the previous stock that is available in the inventory but error say that check your mysql Syntax before WHERE. and this is my query.
"UPDATE tblproducts SET Quantity=Quantity+'"+txtAddQty.Text+"' WHERE ProductId='"+txtProductId.Text+"' "
Where am i wrong. Help
You are concatenating Quantity and String (txtAddQty.Text)
"UPDATE tblproducts SET Quantity = Quantity + " + Convert.ToInt32(txtAddQty.Text) +
" WHERE ProductId='" + txtProductId.Text + "'"
Caution
Above SQL Statement fails if txtAddQty.Text gives alphabets instead of numeric value.
Also will fail if txtProductId.Text gives unexpected value
Not recommended way of doing things with database from application.
Instead of making sql statement by string concatenation you should use parametrized sql query. Doing so will prevent some of the sql injection problem.
imho, Quantity=Quantity+'"+txtAddQty.Text+"' will not work.
you need to remove those ' since you would add a varchar to an int
edit: You also could use a debugger to check the output of your string.
I guess Quantity is numeric, so you should remove the apostrophes ' in your string.
And please do not generate SQL-queries with string concatenation.Use parameterized queries: How do I create a parameterized SQL query? Why Should I?
Try removing the single quotes as you are trying to add it as a number. Only use quotes for strings.
Example:
UPDATE tblproducts SET Quantity=Quantity+"+txtAddQty.Text+" WHERE ProductId='"+txtProductId.Text+"' "
INSERTing values without parameters is fully understandable why it shouldn't be allowed, where you e.g. want to prevent sql-injection. However I do not understand why it's still a big no doing the following as well:
cmd.CommandText = "SELECT * FROM [Students]
WHERE StudentID = " + studentID + ";";
int getID = (int)cmd.ExecuteScalar();
What's the harm in it when just SELECTing? I don't really understand the point with parameters below. I'm not questioning it, I just want to know the reason why parameters is necessary and what consequences I could get from the code above instead using the option below.
var pStudentID = new SqlParameter("#studentID", SqlDbType.Int);
pStudentID.Value = studentID;
cmd.Parameters.Add(pStudentID);
There are two reasons it's better to use parameters.
Sql Injection - Your first example would be susceptible to a sql injection attack. What this means is if the studentID was being input from a web form, some one could use a '-- to comment out the select string and issue other commands against the database.
Prepare - If you use parameters you can prepare the sql statement, which is sort of a precompile of the syntax. This can be slightly more performant in high volume situations.
Edit: I came across this video on reddit the other day, which is a great example of how sql injection works.sql injection
Assume this input:
var studentID = "''; drop table users;--"
cmd.CommandText = "SELECT * FROM [Students]
WHERE StudentID = " + studentID + ";";
This would if calling this select delete the table users completely.
Parameters would help by approving only legitimate input to be added to the query.
I have a column containing many rows. I am passing into a method a list of values. I wish to return all rows where a substring of this column contains the value I am looking for.
At the moment, I am using CHARINDEXto check for a single substring, and appending on OR CHARINDEX for every subsequent substring. It's quite messy, as I am sure you can appreciate.
So, at the moment, I have :
[Long SQL query]...
queryString.Append(string.Format(" (AND CHARINDEX( '{0}', Table.Column ) > 0 ", ListOfValues[0]));
foreach (string value in ListOfValues)
{
queryString.Append(string.Format("OR CHARINDEX( '{0}', Table.Column ) > 0 ", value));
}
queryString.Append(string.Format(")AND CHARINDEX( '{0}', Table.Column) > 0)"));
queryString.Append(")");
Is there are less syntactically horrific way to do this ? :)
Thanks
If I understand the question then you can do this on the SQL side more easily.
Select MyColumn
From MyTable
Where MyColumn Like '%MySubstringText%'
Obviously you would need to create the SQL statement dynamically if your sub string is going to change.
EDIT:
If you've multiple possible substrings then you could populate a table with the list of values and then cross join the two tables and filter using CharIndex.
Create table MySubstrings
(
MySubstring nvarchar(100) not null
)
Select t.MyColumn
From MyTable t, MySubstrings s
Where CharIndex(s.MySubstring, t.MyColumn) > 0
The performance may not be great though.
First off, putting string into a SQL query like that, is very risky! If you don't watch out, you're opening your application up for SQL injection http://en.wikipedia.org/wiki/SQL_injection.
And now to the answer:
queryString.Append(string.Format(" Table.Column LIKE '%{0}%' ", ListOfValues[0]));
To avoid SQL inject, try doing this instead:
command.Parameters.AddWithValue("#ParamX","%" + value + "%");
As we're doing string comparison here, I can't think of a less messy way of handling it with a SQL server.
I have an SQL query of this form
string cmdText = "Select * from " + searchTable
+ "WHERE " + searchTable
+ "Name =' " + searchValue + "'";
Basically what I am trying to do is get a particular actor's info from the database's Actors table. The variable searchTable has the value 'Actor' which is the table name and searchValue has the actor's name (which is represented by the ActorName attribute in the Actor's table, here I am trying to form the name of the attribute by concatenating the words 'Actor' and 'Name' )
So, well, all this concatenation results in (or at least should result in) a query of the form:
Select * from Actor where ActorName ='some actor';
But when I try to run this it gives me the error "Incorrect syntax near '=' " in the browser. Could anyone please help?
You can put (and should!) parameters into your SQL queries for the values in e.g. your WHERE clause - but you cannot parametrize stuff like your table name.
So I'd rewrite that query to be:
SELECT (list of columns)
FROM dbo.Actor
WHERE ActorName = #ActorName
and then pass in just the value for #ActorName.
If you need to do the same thing for directors, you'd have to have a second query
SELECT (list of columns)
FROM dbo.Directors
WHERE DirectorName = #DirectorName
Using parameters like this
enhances security (prohibits SQL injection attacks!)
enhances performance: the query plan for that query can be cached and reused for second, third runs
PS: the original problem in your setup is this: you don't have any space between the first occurence of your table name and the WHERE clause - thus you would get:
SELECT * FROM ActorWHERE ActorName ='.....'
If you really insist on concatenating together your SQL statement (I would NOT recommend it!), then you need to put a space between your table name and your WHERE !
Update: some resources for learning about parametrized queries in ADO.NET:
The C# Station ADO.NET Tutorial / Lesson 06: Adding Parameters to Commands
Using Parameterized Queries with the SqlDataSource
You shouldn't concatenate string to SQL, as this will open you up to SQL Injection attacks.
This is a rather long read about dynamic SQL, but worth reading to understand the risks and options.
You should be using parameterized queries instead, though the only way to use a table name as a parameter is to use dynamic SQL.
I urge you to change your approach regarding table names - this will lead to problems in the future - it is not maintainable and as I mentioned above, could open you to SQL Injection.
The error you are seeing is a result of the concatenation you are doing with the "Where " clause - you are missing a space before it. You are also adding a space after the ' in the parameter ending with "Name".
Your resulting string, using your example would be:
Select * from ActorWHERE ActorName =' some actor';
There is a blank missing and one too much:
searchTable + "Name =' "
should read
searchTable + " Name ='"
Beside that, use SQL parameters to prevent SQL injection.
string cmdText = "Select * from " + searchTable + " WHERE Name = '" + searchValue + "'";