SQL Server : drop table with SQL parameters - sql

I'm trying to drop a table using SqlParameters. I have this code .
dbCon.Open();
DataRowView d= (DataRowView) cmbTabele.Items[cmbTabele.SelectedIndex];
string name = (d["table_name"]as string);
SqlCommand com=new SqlCommand("drop table #nume ", dbCon);
com.Parameters.Clear();
SqlParameter param = new SqlParameter("#nume", name);
com.Parameters.Add(param);
com.ExecuteNonQuery(); // ERROR HERE
dbCon.Close();
I receive this error :
Incorrect syntax near '#nume'.
But when I do
SqlCommand com = new SqlCommand("drop table " + name, dbCon);
it works, and I really don't understand this error.

You cannot use a parameter for a table name. Although you'll normally get told off around here for building up a query using string concatenation, this is one occasion where you'll need to!
SqlCommand com=new SqlCommand("drop table " + name, dbCon);

I do not recommand it, but if you really want to use SQLParameter, then it is possible this way.
SqlCommand com=new SqlCommand("EXEC('drop table ''' + #nume + '''')", dbCon);
But really, there is no advantage in doing it this way. This work on SQL Server 2005 and newest version of it.

Related

SqlCommmand parameters not adding to UPDATE statement (C#, MVC)

If you look at the stuff commented out, I can easily get this to work by adding user input directly in to the query, but when I try to parameterize it, none of the values are being added to the parameters...
This code is throwing an error
Must define table variable #formTable
but the issue is none of the values are adding, not just the table variable (verified by replacing table name variable with static text).
I have many insert statements in this project structured exactly like this one which work perfectly. What am I doing wrong here?
string constr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
//string query = "UPDATE " + s.formTable + " SET " + s.column + " = '" + s.cellValue + "' WHERE MasterID = '" + s.id + "'";
string query = "UPDATE #formTable SET #column = #cellValue WHERE MasterID = #id;";
using (SqlCommand cmd = new SqlCommand(query))
{
//SqlParameter param = new SqlParameter("#formTable", s.formTable);
//cmd.Parameters.Add(param);
cmd.Parameters.AddWithValue("#formTable", s.formTable);
cmd.Parameters.AddWithValue("#column", s.column);
cmd.Parameters.AddWithValue("#cellValue", s.cellValue.ToString());
cmd.Parameters.AddWithValue("#id", s.id.ToString());
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
Parameters are for values, not object identifiers (tables, columns, etc.), so the only valid parameters you have are #cellValue and #id.
If you want to dynamically set table/column names based on user input, you're likely looking at string concatenation. However, that doesn't necessarily mean SQL injection. All you need to do is validate the user input against a set of known values and use the known value in the concatenation.
For example, suppose you have a List<string> with all of your table names. It can be hard-coded if your tables are never going to change, or you can make it more dynamic by querying some system/schema tables in the database to populate it.
When a user inputs a value for a table name, check if it's in the list. If it is, use that matching value from the list. If it isn't, handle the error condition (such as showing a message to the user). So, even though you're using string concatenation, no actual user input is ever entered into the string. You're just concatenating known good values which is no different than the string literals you have now.

VB.NET Oracle SQL "INSERT INTO" with "RETURNING INTO" gives ORA-00933 Command Not Properly Ended

I need to update some code and as part of this I need to insert a row into a table and obtain the id (primary key) of the row just entered.
Have researched this and I believe I should be using RETURNING INTO and Oracle Parameters. I have used parameters in the past successfully to Insert values.
I have an INSERT statement that runs perfectly from VB.NET, but as soon as I add the text "" RETURNING id INTO :myId" I get ORA-00933 Command Not Properly Ended.
Here is a version of the code.
sql = "INSERT ... RETURNING id INTO :myId"
Connect()
Dim intRecsAffected As Integer = 0
Dim comm As OracleCommand = New OracleCommand(sql, _conn)
Dim param As OracleParameter
param = New OracleParameter()
param.ParameterName = ":myId"
param.OracleDbType = OracleDbType.Int32
param.Direction = ParameterDirection.Output ' Tried ReturnValue
comm.Parameters.Add(param)
intRecsAffected = comm.ExecuteNonQuery()
id = comm.Parameters(":myId").Value
Disconnect()
Any ideas?
I believe that your syntax is incorrect:
sql = "INSERT ... RETURNING id INTO myId"
Example below:
https://oracle-base.com/articles/misc/dml-returning-into-clause
Actually, realised what was going on. I cut my full SQL as it's quite long and there's some sensitive stuff in there.
The INSERT was using a SELECT rather than VALUES to get the values for the fields. That won't work - I am guessing because an INSERT with SELECT can add multiple rows even though in this case it won't.
Have re-written the SQL to use VALUES and the VB.Net code works fine.
Thanks to all who replied.

String.Format vs Parameter Values SQL Query

I'm trying to figure out if there is a better way to do this
Dim cmd As New SqlCommand
Dim sel As String
Dim obj As New DataHandler
sel = String.Format("SELECT * FROM Customers WHERE Country LIKE '{0}%'", txt_Input.Text)
cmd.CommandText = sel
Me.dgv_Customers.DataSource = obj.SqlDataRetriever(cmd)
Basically what im trying to do is have a textbox that whenever I type a letter, the grid refreshes itself by sending a Query to my SQL server searching for whatever its in the textbox using the LIKE() from SQL. I've been reading about SQL injection and so far everyone suggests to use parameter values (#value) for user input, but if I try to replace the {0} with that it doesn't work. I just wanna make sure that this is a valid way of doing this.
Thanks
Instead just concatenate the string like below. You should consider using parameterized query to avoid SQL Injection.
sel = "SELECT * FROM Customers WHERE Country LIKE '" + txt_Input.Text + "%'";
Use a parameterized query rather. See This Post
Dim cmd as New SqlCommand("SELECT * FROM Customers WHERE Country LIKE #param")
cmd.Parameters.Add("#param", txt_Input.Text +"%")

SqlCommandBuilder With Convert Statement

I have an application that's built in .NET language.
In this application we mainly read/write to the database (SQL Server 2005).
Sometimes (for a single input) I just use the SQL query, for example:
commandText = "INSERT INTO Test_Table (Number) VALUES ('10')";
command = new System.Data.SqlClient.SqlCommand(commandText, connection);
command.ExecuteNonQuery();
If I want to update a bunch of records in my database, I use the SqlCommandBuilder class, as in this example:
adapter = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM Test_Table WHERE Number = '9'",connection);
commandbuilder = new System.Data.SqlClient.SqlCommandBuilder(adapter);
dataset = new System.Data.DataSet();
adapter.Fill(dataset,"Example");
dataset.Tables["Example"].Rows[0].["Number"] = 10;
adapter.update(dataset,"Example");
These work great. But now, for some reason I need to insert/update datetimes and use the CONVERT function on it.
The single SQL query works great:
t = System.DateTime.Now;
commandText = "INSERT INTO Test_Table (DateTime) VALUES (datetime, 't.toString()', 103)";
command = new System.Data.SqlClient.SqlCommand(commandText, connection);
command.ExecuteNonQuery();
This works without a problem, however I have no idea how to achieve the same thing using my SqlCommandBuilder scripts. I could change everything to single query, but this would take a week.
I have already tried the following, without success:
t = System.DateTime.Now;
adapter = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM Test_Table WHERE Number = '9'", connection);
commandbuilder = new System.Data.SqlClient.SqlCommandBuilder(adapter);
dataset = new System.Data.DataSet();
adapter.Fill(dataset, "Example");
dataset.Tables["Example"].Rows[0].["DateTime"] = "CONVERT(datetime,'" + t.toString() + "',103);
adapter.update(dataset, "Example");
This line of code is weird:
dataset.Tables["Example"].Rows[0].["DateTime"] = "CONVERT(datetime,'" + t.toString() + "',103);
Does it compile? Specifically, this:
.Rows[0].["DateTime"]
I think it should be:
.Rows[0]["DateTime"]
But regardles of the syntax...I don't think this is the right way to go. The datatable (in the dataset) expects a datetime object (btw, don't name your attributes by their datatype, it causes confusion) and you are providing it with something that is incompatible. Sytem.DateTime.Now returns a DateTime object, then you are concatenating it with string (again, does this compile?) and I assume you expect it to be injected into the INSERT statement?
Since you said that it would take a week to change everything, I assume that you have a lot of similar code to repair.
I see three possible solutions, all require some work:
Create a database trigger
https://msdn.microsoft.com/en-us/library/ms189799.aspx
Add a default value to the DateTime field in the database and remove the DateTime from the select query.
http://www.w3schools.com/sql/sql_default.asp
https://www.youtube.com/watch?v=INfi7jkdXC8
(start watching at around 2:00)
You can write a function that does the actual text replacing but it can get tricky:
dasdas as
private string ChangeDate(string insertQuery)
{
// find the location of the date column
// replace the actual value with the "CONVERT(datetime,'" + actualValue + "',103)"
// return the new value and store it in the sqlcommandbuilder.insertstatement
}
Admittedly, all three require work and are not really "elegant". I would go for option 2, because it seems less work. But I don't know if this solves your problem..

Can't retrieve data from the database

I'm a little in need of your help
In my web application I have this Select statement, but once I run it, it retrieves 0 data but when I try my Select statement in the database it has data in it, and my Select statement is correct, by the way my application is already published in the server.
Here's my code
string SelectStatement = "SELECT DATEDIFF(day, kg1653, GETDATE()) datenum, kg1635, (CASE WHEN kg1637 is null THEN 0 END) eis ";
string FromStatement = "FROM hsi.keygroupdata503 ";
string WhereStatement = "WHERE kg1235='" + _securityCode + "' and kg1241 is null";
_sqlDT = ConnectToDatabase(SelectStatement + FromStatement + WhereStatement);
and here's my connection string
System.Data.Odbc.OdbcConnection _odbcConn = new System.Data.Odbc.OdbcConnection();
_odbcConn.ConnectionString = "MY DATABASE CONNECTION STRING";
System.Data.Odbc.OdbcDataAdapter _odbcA = new System.Data.Odbc.OdbcDataAdapter(sqlQuery1, _odbcConn);
DataTable _odbcDt = new DataTable();
_odbcA.Fill(_odbcDt);
return _odbcDt;
Can somebody please help me with this?
Thank you so much!
When does sqlQuery1 get set to _sqlDT ... your best bet is to debug and see what the query is right on the line of it being called and copy it to run on the SQL server in case something else is updating it or _scurityCode is empty. Also if you have a test environment with similar table names, make sure you are connecting to the same live instance.
Side note, not foolproof but make sure _securityCode has a replace statement and change all single quotes to double quotes to work against SQL injection as the commentor above said.