Reseting SQL Application role after the connection has been closed - sql-server

I'm using sql application roles from a .net application. I have an issue which occurs when the connection is lost. So as an example I have this block of code which opens a connection, sets the app role, does a select from the database and the disposes my connection. If I run this code a 2nd time it fails when trying to set the app role again (the ExecuteNonQuery() line for the sys.sp_setapprole).
The exception is an SqlException: A severe error occurred on the current command. The results, if any, should be discarded.
I've tried using the #fCreateCookie parameter and calling sys.sp_unsetapprole to reset the role but this makes no difference.
Help please?
using (SqlConnection connection = new SqlConnection(myConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("sys.sp_setapprole", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#rolename", "MyRole");
command.Parameters.AddWithValue("#password", "MyPassword");
command.ExecuteNonQuery();
}
try
{
DataSet ds = new DataSet();
using (SqlCommand command = new SqlCommand("dbo.MyProcedure", connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.CommandType = CommandType.StoredProcedure;
adapter.Fill(ds);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Related

Can't login to remote SQL server

I wrote a little app to test connection to a remote SQL server using the following code:
SqlConnection myConnection = new SqlConnection();
SqlConnectionStringBuilder bu = new SqlConnectionStringBuilder();
bu.DataSource = #"<server>";
bu.InitialCatalog = "<database>";
bu.IntegratedSecurity = false;
bu.UserID = "<user id>";
bu.Password = "<password>";
myConnection.ConnectionString = bu.ConnectionString;
try
{
myConnection.Open();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
I am getting the unhelpful message "login failed for user...". I can login using that user on the server itself so the credentials are correct. I have also set the database to accept remote logins. I can ping back and forth to the server.
Is there a way to further test this to try and diagnose the problem?

Export CSV file to FTP site using SQL

Does anyone know how to export CSV file to FTP site in SQL management studio?
I am currently using
exec xp_cmdshell 'net use \ftp://213.32.32 \user:fjdowj ddfdf'
But it doesn't work at all
Thanks
you can try CLR stored procedure to generate CSV file and export to FTP site.
Generating CSV file to a path is given below:
public static void GenerateCSVFile(SqlString queryToGetData, SqlString folderPath)
{
string sqlCommand;
string filePath;
try
{
sqlCommand = queryToGetData.ToString();
filePath = folderPath.ToString() + "\\GeneratedFile" + ".csv";
using (SqlConnection connection = new SqlConnection(
"context connection=true"))
{
connection.Open();
SqlCommand command = new SqlCommand(sqlCommand,connection);
using (SqlDataReader reader = command.ExecuteReader())
{
DataTable table = new DataTable();
table.Load(reader);
StringBuilder builder = new StringBuilder();
List<string> columnNames = new List<string>();
List<string> rows = new List<string>();
foreach (DataColumn column in table.Columns)
{
columnNames.Add(column.ColumnName);
}
builder.Append(string.Join(",", columnNames.ToArray())).Append("\n");
foreach (DataRow row in table.Rows)
{
List<string> currentRow = new List<string>();
foreach (DataColumn column in table.Columns)
{
object item = row[column];
currentRow.Add(item.ToString());
}
rows.Add(string.Join(",", currentRow.ToArray()));
}
builder.Append(string.Join("\n", rows.ToArray()));
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.Write(builder.ToString());
}
}
}
}
catch(Exception ex)
{
throw;
}
}
Once you generate file, you can use the below approach to load to FTP path.
FTP Directly in SQL
xp_cmdshell is disabled by default (for very good reasons) on all recent versions of SQL Server. You could re-enable it manually (and I encourage you NOT to), but then you'd need an ftp command line tool to do the upload-- I don't think that net use command is going to do the trick. If you did manage to map an ftp end point as a drive with net use as the SQL Server service user, you would still need to achieve copying the file from SSMS to the filesystem on the server before running the FTP job.

Using a SQL Server mdf file easy on any Windows without any authentication

I have a SQL Server .MDF database file that contains data and tables that I need to load into my project and add or update that data so when I attach the file and run my program on a second PC that has SQL Server already installed, I get error that database is not found!
Note1: database was created in SQL Server 2012 local host server and Windows authentication mode.
I am using this code for loading and using database :
SqlConnection c = new SqlConnection(#"Data Source=.;Initial Catalog=db1;Integrated Security=True");
private void Form1_Load(object sender, EventArgs e)
{
String str;
SqlConnection myConn = new SqlConnection(#"Data Source=.;Initial Catalog=db1;Integrated Security=True");
str = "CREATE DATABASE db1";
SqlCommand myCommand = new SqlCommand(str, myConn);
try
{
myConn.Open();
myCommand.ExecuteNonQuery();
MessageBox.Show("First db is Created", "MyProgram", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (System.Exception ex)
{
// MessageBox.Show("DB is exist");
}
finally
{
if (myConn.State == ConnectionState.Open)
{
myConn.Close();
}
}
using (SqlConnection con = new SqlConnection(#"Data Source=.;Initial Catalog=db1;Integrated Security=True"))
{
try
{
//Open.the SqlConnection;
con.Open();
//The following code uses a SqlCommand based on the SqlConnection
using (SqlCommand command = new SqlCommand("CREATE TABLE contents(id int IDENTITY(100, 1),Name char(50) NOT NULL,Lastname char(50) NOT NULL,Number char(50) ,Area nvarchar(50) ,Date nvarchar(50)NULL,Duration nvarchar(MAX),description nvarchar(MAX),gender nvarchar(50),number2 nvarchar(50),DT datetime NULL);", con))
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//MessageBox.Show("Tables created");
}
}
}
Load table
private void button4_Click(object sender, EventArgs e)
{
SqlDataAdapter a = new SqlDataAdapter("select * from contents", c);
DataTable t = new DataTable();
a.Fill(t);
dataGridView1.DataSource = t;
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;
dataGridView1.AutoResizeColumns();
}
But it's not very unique and useful the db will be moved every day to another PC and it must load perfectly also I have some table in SQL file that are static and their is no need to code for them, I want to just use them as resource. Also I heard about some method that embedded or local db can be used as db in app data folder and can be moved with app wisely so I need some help here. Thanks
instead of creating a raw db everytime, you can use your mdf file as source,like below
Create database dbname
On
(
Filename= 'path where you copied mdf file'
)
For attach;

Connection property has not been initialized Error (ExecuteNonQuery)

This question has been addressed all over the web and I tried a lot of things without success. The SQL EXPRESS service is setup to accept local system account but the problem still exists.
This is my connection string:
<add name="PhoneTemplateChange" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Database=PhoneTemplateChange;Integrated Security=SSPI" />
I created a class to do database operations in the constructor I have
_connectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["PhoneTemplateChange"].ConnectionString;
and a method in this class to insert data
public void AddNewChangeOrder(int operation, int targetExt)
{
using (SqlConnection con = new SqlConnection(_connectionString))
{
string sql = "INSERT into [dbo].ChangeOrder (operation, targetExt, dtrequested) VALUES (#operation, #targetExt, #dtrequested)";
using (SqlCommand cmd = new SqlCommand(sql))
{
try
{
cmd.Parameters.AddWithValue("#operation", operation);
cmd.Parameters.AddWithValue("#targetExt", targetExt);
cmd.Parameters.AddWithValue("dtrequested", DateTime.Now);
//con.CreateCommand();
con.Open();
//cmd.InitializeLifetimeService();
int rows = cmd.ExecuteNonQuery();
con.Close();
}
catch (SqlException e)
{
throw new Exception(e.Message);
}
}
}
I have played around with the connection string trying all different suggestions, also the commented code in the method above is what I tried to solve the problem. Still no luck!
I also changed the connection string I get two different exceptions this way
Database=PhoneTemplateChange
The above gives the exception in the title.
And the following gives the Exception "Cannot open Database PhoneTemplatechange.mdf requested by the login. Login failed for user 'mydomain\myusername'"
Database=PhoneTemplateChange.mdf
Any ideas?
You are missing the line of code where you specify that cmd uses con as it's connection. As a result the Command (cmd) has no connection, and con isn't associated with any command at all.
Add this line before executing:
cmd.Connection - con;
Alternatively (and better IMO) change your using statement as follows:
using (SqlCommand cmd = new SqlCommand(sql, con))

Disposing the Sql Connection

Just wondering, Would the SqlConnection be diposed/closed when this method is done? Or do i have to explicitly call the close method at the end?
using (SqlCommand cmd = new SqlCommand(sql, GetConnection()))
{
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
}
}
SqlConnection GetConnetion()
{
return new SqlConnection("connectionstring");
}
I know i can do something like this:
SqlConnection conn = GetConnetion();
SqlCommand cmd =new SqlCommand(sql, conn);
//Do Something
conn.Close()
cmd.Dispose()
But just curious how the using block will work in this case.
Cheers
No, the connection object won't be automatically disposed in your example. The using block only applies to the SqlCommand object, not the connection.
To ensure that the connection is disposed, make sure that the SqlConnection object is wrapped in its own using block:
using (SqlConnection conn = GetConnection())
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
// don't forget to actually open the connection before using it
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something
}
}
}
Luke's answer is the correct one in terms of what you specifically asked regarding the disposal of the connection.
For completeness, what you could also do is to use the SqlCommand.ExecuteReader(CommandBehaviour) method instead of the parameterless one, passing in CommandBehvaiour.CloseConnection:
using (SqlCommand cmd = new SqlCommand(sql, GetConnection()))
{
using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{}
}
}
This signifies that when the SqlDataReader is closed (when it is disposed of in the using construct), it will in turn close the connection that it is using.
I'm not keen on this approach though, as there is some implied logic and it is not obvious what exactly is closing the connection.
The using statement will take care of this for you.
Oops. You want to use the using on your connection, not on your command.
Use using but on the connection, not on the SqlCommand. The Dispose method on the connection will close the connection (return it to the pool, if pooling is enabled). Also place an using around the SqlDataReader too:
using(SqlConnection conn = GetConnection())
{
SqlCommand cmd = new SqlCommand(sql, conn);
using (SqlDataReader reader = cmd.ExecuteReader())
{
do
{
while (reader.Read())
{
}
} while (reader.NextResult());
}
}
Here and Here is something which could help you understanding what is going on.

Resources