My project has different SQL Server DataTable. I will bind the data from user request table. so got table name as
Example:
table = "MyTable"
How to write the SQL query for select the particular table.
con.open();
SqlAdaptor da = new SqlAdaptor ("select * from '" + table.replace(""", "\"")" + '")
cmd.ExecuteNonQuery();
My replace is not working so I hope to any one resolve my issue.
Just escape " character?1
table.Replace("\"", string.Empty);
Also you don't need single quotes for your table name. By the way if you get this table as an input, I will strongly suggest do some strong validation before you put it in your query or use a whitelist.
You didn't show us rest of your code but use using statement to dispose your connection and adapter objects.
1: Since it is an escape sequence character
You can also try
SqlAdaptor da = new SqlAdaptor ("Select * from " + table.Replace('"', ' ').Trim());
string table = "MyTable";
table.Replace('\"', ' '); //Or
table.Replace('\"',string.Empty);
Related
I want to use selected item from my combo box for my SqlDataReader.
Which wrong in my syntax?
string varfunction = cbFunctionClass.SelectedItem.ToString();
con.Open();
SqlCommand sqlFunName = new SqlCommand("SELECT " + varfunction + " FROM sdn_cd_allclass WHERE MIDCLASS_CODE = '" + cbMiddleClass.Text + "'", con);
SqlDataReader sqlFunNameReader = sqlFunName.ExecuteReader();
while (sqlFunNameReader.Read())
{ lbFunctionClassName.Text = sqlFunNameReader[varfunction].ToString(); }
sqlFunNameReader.Close();
con.Close();
I need to use varfunction to select SQL column.
If varfunction contains a single digit, your query would read something like
SELECT 7 FROM sdn_cd_allclass...
for example. This would not select a column named 7 but the literal 7, i.e. an integer with the value of 7. And the column in the result, that holds this integer has no name, especially isn't its name 7.
If you want to select a column named 7 (which probably isn't the best idea BTW) you have to quote it by putting square brackets around it, so that the query becomes
SELECT [7] FROM sdn_cd_allclass...
So try
... "SELECT [" + varfunction + "] FROM sdn_cd_allclass..." ...
And as an aside, like already commented many times, I also recommend you to rework this and use parameterized queries (for the literals, i.e. the value in the WHERE clause of your current query, it won't work with identifiers, i.e. the column name).
I was given a task to rewrite an old web API.
This API reads SQL queries from the database.
There's literally a view with "Queries" in the name which contains "SqlText" column.
SELECT SqlText FROM Queries WHERE QueryID = 123
The "SqlText" contains only simple SQL queries in the format SELECT [columns] FROM [table] by convention.
The query is altered depending on the URL parameters in the request. The result of this query is then shown as result.
string parsedColumns = ParseColumns(queryRow); //contains "Column1, Column2";
string parsedTable = ParseTable(queryRow); //contains "SomeTable"
string requestColumns = HttpContext.Request["columns"];
string sqlColumns = requestColumns ?? parsedColumns;
string col1Condition = HttpContext.Request["Column1"]
string col2Condition = HttpContext.Request["Column2"]
string sqlQuery = "SELECT " + sqlColumns
+ " FROM " + parsedTable
+ " WHERE Column1 = " + col1Condition
+ " AND Column2 = " + col2Condition;
This is obvious SQL injection issue so I started rewritting it.
Now there are three other problems.
I cannot change the structure of the database or the convention
The database is either Oracle or SQL Server
I don't know how to correctly work with the "columns" URL parameter to avoid SQL injection.
It's easy to convert the URL parameters in the WHERE clause to the SQL parameters for both SQL Server and Oracle.
SQL Server
var sqlCommand = new SqlCommand("SELECT * FROM SomeTable WHERE Condition1 = #con1 AND Condition2 = #con2");
Oracle
var oracleCommand = new OracleCommand("SELECT * FROM SomeTable WHERE Condition1 = :con1 AND Condition2 = :con2");
Column identifiers
The problem is with the HttpContext.Request["columns"]. I still need to somehow alter the SQL query string with URL parameters which I don't like at all.
To simplify the issue, let's consider a single column from URL request.
string column = HttpContext.Request["column"];
var cmd = new SqlCommand($"SELECT {column} FROM ...");
I know that in SQL Server the identifier can be surrounded by braces. So my line of thinking is that I'm safe if I strip all braces from the column.
string column = HttpContext.Request["column"];
column = column.Replace("[", "").Replace("]", "");
column = $"[{column}]";
var cmd = new SqlCommand($"SELECT {column} FROM ...");
Oracle uses quotation marks.
string column = HttpContext.Request["column"];
column = column.Replace("\"", "");
column = $"\"{column}\"";
var cmd = new OracleCommand($"SELECT {column} FROM ...");
The question
Is this sql-injection safe enough?
Or is this use case inherently sql-injection unsafe?
Since you are working with a basic program design that you cannot change what about just trying to add edits to the input to look for injection elements. For example if the input is a column name it will need to have a maximum length of 30 (before 12.x) characters and should not contain a semicolon or the strings " OR" or " AND" in them. While not a perfect solution this should be practical solution.
I'm trying to query a CSV file. It works when I do a simple select, but as soon as I try to add a where clause, I run into No value given for one or more required parameters.
Obviously, it sounds like it's not getting the supplied parameter, but I've tried to pass it in a number of ways. See below for some code samples
DateTime lastRunDate = Convert.ToDateTime(ConfigurationManager.AppSettings["LastRunDate"]);
OleDbConnection conn = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + base.applicationRoot + ";" +
"Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited\"");
// This works just fine
//OleDbDataAdapter adapter = new OleDbDataAdapter(String.Format("select * from {0}",
// This gives the error
OleDbDataAdapter adapter = new OleDbDataAdapter(String.Format("select top 100 * from [{0}] where {0}.sale_date = #sDate", base.csvFileName), conn);
//adapter.SelectCommand.Parameters.Add("#sDate", OleDbType.DBDate).Value = lastRunDate;
adapter.SelectCommand.Parameters.AddWithValue("#sDate", lastRunDate);
// This also gives the same error as above
//OleDbDataAdapter adapter = new OleDbDataAdapter(String.Format("select top 100 * from {0} where sale_date = '{1}'", base.csvFileName, lastRunDate), conn);
base.csvFileName, lastRunDate.ToShortDateString()), conn);
DataTable dt = new DataTable();
adapter.Fill(dt);
I don't know anything about C#, and I'm still decently new to SQL, but perhaps it's the SELECT TOP part of your query. I know that SELECT TOP isn't really accepted on all db systems, and that it's included in both of your queries that are giving you problems. Have you tried removing that and using LIMIT instead?
"select top 100 * from [{0}] where {0}.sale_date = #sDate"
to
"select * from [{0}] where {0}.sale_date = #sDate LIMIT 100"
I would have added this as a comment as it's not a concrete answer, but I have not the required rep yet.:(
Remove this line. You have added parameter twice.
adapter.SelectCommand.Parameters.AddWithValue("#sDate", lastRunDate);
and make sure the value is present in lastRunDate variable. it should not be null.
EDITED:
Remove table name from the where condtion, Use like this
select top 100 * from [{0}] where sale_date=#sDate
Column Names in the Excel file and in the Query are not Same.
Either column name is missing.
Column Name not existing in the Excel File.
I found he issue with this. The query simply didn't understand the column names.
I thought that setting HDR=Yes meant that the oledb would read the first row headers, hence know them. But it wasn't until I added a schema.ini file that I managed to query in this way.
Here's some more about schema.ini files
I am new to .net/C#. Coming from PHP and some Java, I am finding the new languages interesting and challenging.
I have an issue with a sql string
string query = #"select * from Users where role='member' and
SUBSTRinG(lname, 1, 1) = '"+querystring + "' ORDER BY lname ASC";
Which to me, looks fine. however when run my solution and output the query as it is not working, I get this as my output:
select * from Users where role='member' and SUBSTRinG(lname, 1, 1)
= ' O ' ORDER BY lname ASC
This is output into my Firebug console (the page that uses this query is accessed via AJAX).
Is their a reason my 's are being turned into their code version, ie '''
Thanks
In C# you should be using SqlCommand to excute the query, and to prevent sql injection using the parameter collection.
Your query seems fine - The issue might be the way you are running it or the parameters being supplied. Update your question with more details on what you are expecting vs what is happening, include any error messages generated.
Below is a general guideline of how to get data from a sql table to a c# Data Table object.
SqlConnection conn = new SqlConnection("YourConnectionString");
SqlCommand cmd = new SqlCommand(#"select * from Users where role='member' and
SUBSTRinG(lname, 1, 1) = #query ORDER BY lname ASC");
cmd.Parameters.AddWithValue("#query", querystring);
DataTable resultTable = new DataTable();
try
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(resultTable);
} finally {
if (conn.State != ConnectionState.Closed) conn.Close();
}
Console.WriteLine(String.Format("Matched {0} Rows.", resultTable.Rows.Count));
For SQL injection protection:
You can provide escape sequence for single quotes by replacing them with two single quotes '' so that it will be treated as a single quote inside SQL strings. Otherwise it is considered as a start or end of the string value in SQL.
Replacing single quotes using ' in .net is also preferred but its better going with two single quotes.
Here in the code I am trying to retrieve information from a database and store it in a table. In query i have used a variable to specify a table, i am doing so because i want to use this single piece of code to retrieve information from various tables based on which table name the variable "a" contain but when i am executing this it's throwing me an exception. please help...
MyOleDbConnection.Open();
string a = "login";
string query = string.Format("select Email,Username,PhoneNo,Department from '{1}' where Email='{0}'", editrecordtextBox.Text,a);
DataTable dt = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter();
da = new OleDbDataAdapter(query, MyOleDbConnection.vcon);
da.Fill(dt);
Note- this is just the part of the code, the exception is occuring in this code only.
Your code is in fact working correctly.
First of all, remove your single quotes around the table name. These mark a text, not an identifier or name.
I can imagine that login is a reseverd name you cannot use as plain text in your SQL. Depending on the database you can quote your tablename so it is recognizes as a name, not an reserved word.
For SQL-Server it would be done with [ and ]:
string query = string.Format("select Email,Username,PhoneNo,Department from [{1}] where Email='{0}'", editrecordtextBox.Text,a);
If you would give us your database, we could help.
the way that tested and Worked is something like Below as you see the Table Name is Variable Form i Make a query with concatenate 3 section together
string query = "SELECT TOP 1 * FROM M" + TableName.ToString() + " ORDER BY ID
DESC";