Right now I am able to execute a script from my website in an HTTPpost method.
string scriptDirectory = "c:\\Users\\user\\Documents";
string sqlConnectionString = "Integrated Security=SSPI;" +
"Persist Security Info=True;Data Source=ARES";
DirectoryInfo di = new DirectoryInfo(scriptDirectory);
FileInfo[] rgFiles = di.GetFiles("*.sql");
foreach (FileInfo fi in rgFiles)
{
FileInfo fileInfo = new FileInfo(fi.FullName);
string script = fileInfo.OpenText().ReadToEnd();
SqlConnection connection = new SqlConnection(sqlConnectionString);
Server server = new Server(new ServerConnection(connection));
server.ConnectionContext.ExecuteNonQuery(script);
connection.Close();
}
Atm the script is creating a new database (database is not dynamic yet). I want to pass in parameters that a user of the website enters and then pass that into the sql script. Basically I want them to choose the name of the database that is to be created.
The SQL command's are right at the beginning of the script.
CREATE DATABASE [This is where the name will be passed to]
GO
USE[This is where the name will be passed to]
Edit:
I have this code
SqlCommand createDbCommand = new SqlCommand();
createDbCommand.CommandText = "CREATE DATABASE [#DataBase]";
createDbCommand.Parameters.Add("#DataBase", SqlDbType.Text);
createDbCommand.Parameters["#DataBase"].Value = client.HostName;
Must I manually enter this into the top of my script now?
Create a new SqlCommand and set the script CommandText to your script's text and then set parameters using cmd.Parameters.Add.
Using parameters with CRUD operations is simple enough (google for "t-sql parameters" for thousands of resources), however parameterising type names is more involved, for that there's a lengthy MSDN article here: http://msdn.microsoft.com/en-us/library/bb510489.aspx
If you're looking for something quick 'n' dirty, you could roll your own parameterisation system by putting replacement sequences in your sql files and using a regular expression to make each replacement, such as using the syntax "{{fieldName}}".
Related
I have an ASP.NET application that passes a Datatable to a web service, then from the web service to a SQL Server stored procedure. When I publish the web application and web service to the server and run, it fails. When I run the application from the local host pointing to the web service on the server, it works fine. When I run the both the web application and web service from localhost, it works fine.
I did some troubleshooting and see that the following line is the problem but I am not sure how to solve:
cmdCommit.Parameters.AddWithValue(#SourceTable, dtSource);
When I comment the line above, everything works. When I replace the reference to the DataTable (dtSource) in the line above with a string datatype, it works.
Here is the entire web method, I am using this code within a try/catch block:
DataTable dtSource = ObjectToData(sourceTable);
dtSource.TableName = TableTypeObject;
using (SqlConnection cnn = new SqlConnection(_cnnSqlCapss))
{
SqlCommand cmdCommitChange = new SqlCommand("usp_Stored_Procedure", cnn);
cmdCommitChange.CommandType = CommandType.StoredProcedure;
cmdCommitChange.Parameters.AddWithValue("#Parm1", Value1);
cmdCommitChange.Parameters.AddWithValue("#Parm2", Value2);
cmdCommitChange.Parameters.AddWithValue("#Parm3", dtSource);
var returnParameter = cmdCommitChange .Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
cnn.Open();
cmdCommitChange .ExecuteNonQuery();
var result = returnParameter.Value;
return (int)result;
}
The confusing part is that when I run the web application from the localhost and reference the web service on the server, it works. I don't understand why it fails when I run the web application from the server.
When I comment the line that reference the DataTable everything works.
I have tried the following and still no success:
SqlParameter tvpParam cmdCommit.Parameters.AddWithValue "#SourceTable", dtSource);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.SourceTableType";
Also, The web method is not throwing an exception.
Assumed you're already doing these:
Defining table type in User-Defined Table Types in your database (often known as TVP, see reference section below);
Adding parameter to pass DataTable to stored procedure (e.g. #SourceTable).
Then, you can use SqlDbType.Structured to pass DataTable contents as stored procedure parameter like this:
cmdCommitChange.Parameters.Add("#SourceTable", SqlDbType.Structured).Value = dtSource;
Alternative with AddWithValue:
cmdCommitChange.Parameters.AddWithValue("#SourceTable", dtSource).SqlDbType = SqlDbType.Structured;
Example usage in SqlConnection block:
using (SqlConnection cnn = new SqlConnection(_cnnSqlCapss))
{
SqlCommand cmdCommitChange = new SqlCommand("usp_Stored_Procedure", cnn);
cmdCommitChange.CommandType = CommandType.StoredProcedure;
cmdCommitChange.Parameters.AddWithValue("#Parm1", Value1);
cmdCommitChange.Parameters.AddWithValue("#Parm2", Value2);
cmdCommitChange.Parameters.AddWithValue("#Parm3", Value3);
// add this line
cmdCommitChange.Parameters.Add("#SourceTable", SqlDbType.Structured).Value = dtSource;
cmdCommitChange.Parameters.Add("#ReturnVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
cnn.Open();
cmdCommitChange.ExecuteNonQuery();
var result = (int)returnParameter.Value;
return result;
}
Reference:
Table-Valued Parameters (MS Docs)
I found the problem. I am passing a text value that is too large for a column on my datatable.
The web service was indeed throwing an exception but there was some code in my application's routine which was preventing me from seeing it.
I am trying to update my database with the window form I have created, however an error occurred when I execute the code:
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.Data.dll" at comm.ExecuteNonQuery();
Here is the code that I used to connect to my database. Was the code I used to update the database wrong?
string conn=ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
SqlConnection connection = new SqlConnection(conn);
SqlCommand comm = new SqlCommand("UPDATE ExerciseInstruction SET Accumulated_Daily_Sets_Completed = '0' WHERE ExerciseInstructionsID ='" + exerciseInstructionID +"'", connection);
comm.ExecuteNonQuery();
Here is the complete error message :
ExecuteNonQuery requires an open and available Connection. The
connection's current state is closed.
The error message explain all. The command cannot be executed if the code doesn't know how to reach the database. Just a call to connection.Open should fix the problem, however I think you need to use a proper way to execute the query.
This is called Parameterized query. In this way you don't concatenate strings together to form you query text but use parameters to pass values to the database engine and a special formatted string containing the parameters placeholders.
There are two main advantages to do so. It is not possible to target your code with Sql Injection hacks and you don't have to handle quoting around your strings (an infinite source of bugs)
string conn=ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
string cmdText = #"UPDATE ExerciseInstruction
SET Accumulated_Daily_Sets_Completed = 0
WHERE ExerciseInstructionsID =#exid";
using(SqlConnection connection = new SqlConnection(conn))
using(SqlCommand comm = new SqlCommand(cmdText, connection))
{
connection.Open(); // Need this before executing the query
comm.Parameters.Add("#exid", SqlDbType.Int).Value = exerciseInstructionID;
comm.ExecuteNonQuery();
}
I'm a new in the world of coding,
I built a large web site with several textboxes, so now i figure out that I've been using a dangerous method of inserting data in the SQL server by some thing like this:
execSQL("insert into Dossier(ID_Dossier,Nom_Giac) values(" & id_dossier.text & "," Nom_gaic.text & "')")
Public Function execSQL(ByVal req As String, Optional ByVal type As String = "r")
cmd = New SqlCommand
cmd.CommandText = req
cmd.Connection = con
openCon()
If type = "r" Then
Return cmd.ExecuteReader(CommandBehavior.CloseConnection)
Else
Return cmd.ExecuteNonQuery
End If
closeCon()
End Function
I just want to know if there is any quick way to solve this problem in my entire web site.
I applaud the fact that you want to remove any possibilities of SQL injection from your site.
That said, there's no quick, magical "find-and-replace-my-vulnerable-code" function; you need to go into your system and update any calls like that with parameterized queries.
Parameterized queries are required to prevent SQL injection. Here's an example, taken from this question: How do I create a parameterized SQL query? Why Should I?
Public Function GetBarFooByBaz(ByVal Baz As String) As String
Dim sql As String = "SELECT foo FROM bar WHERE baz= #Baz"
Using cn As New SqlConnection("Your connection string here"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("#Baz", SqlDbTypes.VarChar, 50).Value = Baz
Return cmd.ExecuteScalar().ToString()
End Using
End Function
Using LINQ to SQL can help prevent SQL Injection attacks by parameterizing for you:
LINQ to SQL passes all data to the database via SQL parameters. So, although the SQL query is composed dynamically, the values are substitued server side through parameters safeguarding against the most common cause of SQL injection attacks.
Read more about it here.
I write this C# Code for insert one text data to my database table:
SQLiteConnection con = new SQLiteConnection("Data Source=tDB1.sqlite;Version=3;");
string q1 = "INSERT INTO tMembers(mName) VALUES(?)";
SQLiteCommand cmd1 = new SQLiteCommand(q1, con);
cmd1.Parameters.AddWithValue("#mName", txtName.Text);
con.Open();
cmd1.ExecuteNonQuery();
con.Close();
I copy my tDB1.sqlite to my program folder and Create tMembers table in sqlite.
when i run my program, program debugger show ""cmd1.ExecuteNonQuery();"" line and display to me: SQLite error no such table
can any help me?
thank you.
It is a little to weak look for a file based just on current directory. If you are sure the database is placed exactly in the same dir of the executable ( that is when debugging from visual studio $projectdir$\bin\debug you can enforce the path as in the following code:
SQLiteConnection con = new SQLiteConnection(string.Format("Data Source={0};Version=3;"
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"tdb1.sqlite"))
);
Change the command string
string q1 = "INSERT INTO tMembers(mName) VALUES(?)";
to
string q1 = "INSERT INTO tMembers(#mName) VALUES(?)";
There is no need to keep corresponding to the column's name, but it must be the same with the args' name when executing the whole command. More info about this, you could search "PL/SQL" in google.
Besides, did you execute this command with "VALUES(?)"? I'm not sure that could work or not, you could execute INSERT INTO tMembers(#mName) DEFAULT VALUES instead, if there is no NOT NULL constraint.
I`m having problems between two servers, wich use differente odbc dsn.
My apps work great but crystal reports uses the original odbc connection, how can I fix this?
I'm thinking of using the same connection string in the web.config, but I don't know how.
found this but is too confusing for me
thanks,
You can't use a connection string in the same way you can with an ado.net connection. However, you can certainly use values from the web.config to specify the connection info. Create an instance of the ConnectionInfo class and set the ServerName, DatabaseName, UserID, and Password properties. Then attach it to each of the tables in the report:
ConnectionInfo reportConnectionInfo = new ConnectionInfo();
reportConnectionInfo.ServerName = ConfigurationManager.AppSetting["ServerName"];
reportConnectionInfo.DatabaseName = ...;
reportConnectionInfo.UserID = ...;
reportConnectionInfo.Password = ...;
foreach (Table table in reportDocument.Database.Tables) {
table.LogOnInfo.ConnectionInfo = reportConnectionInfo;
}
If you try to use this suggestion, beware of my sloppy typing...
You can use the connection string.
You have to create an instance of the database provider ConnectionStringBuilder passing in the Connection String pulled from a config file. Here is an example in VB.
Dim connString As String = ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString
Dim connStringBuilder As SqlConnectionStringBuilder = New SqlConnectionStringBuilder(connString)
Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
myConnectionInfo.DatabaseName = connectionStringBuilder.InitialCatalog
myConnectionInfo.UserID = connectionStringBuilder.UserID
myConnectionInfo.Password = connectionStringBuilder.Password
myConnectionInfo.ServerName = connectionStringBuilder.DataSource