Access to SQL Server messages via ADO.NET - sql-server

Is it possible to access the SQL Server "by-product messages" via ADO.NET? Due to the lack of words, by "by-product messages" I mean the output which appears in the Messages tab in Microsoft SQL Server Management Studio. What I particularly have it mind is to read the output of SET STATISTICS TIME ON. It appears that SqlDataReader does not offer anything in this matter.

Yes, there's an event on the SqlConnection class called SqlInfoMessage, which you can hook into:
SqlConnection _con =
new SqlConnection("server=.;database=Northwind;integrated Security=SSPI;");
_con.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler);
The event handler will look like this:
static void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e)
{
string myMsg = e.Message;
}
The e.Message is the message printed out to the message window in SQL Server Management Studio.

Thank you for the response above. I just did a little experiment and found a little unexpected glitch (a bug?) when reading messages (in this case produced by SET STATISTICS TIME ON) from a multi-recordset result. As indicated below, one has to call NextResult even after the last resultset in order to get the last message. This is not needed in the case of a single recordset result.
using System;
using System.Data.SqlClient;
namespace TimingTest
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("some_conn_str");
conn.Open();
conn.InfoMessage += new SqlInfoMessageEventHandler(Message);
SqlCommand cmd = new SqlCommand("some_sp", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read()) { };
rdr.NextResult();
while (rdr.Read()) { };
// this is needed to print the second message
rdr.NextResult();
rdr.Close();
conn.Close();
}
static void Message(object sender, SqlInfoMessageEventArgs e)
{
Console.Out.WriteLine(e.Message);
}
}
}

Based on marc_s' answer, I ve created a wrapper class
public class SqlInfoMessageWrapper
{
public SqlInfoMessageWrapper(SqlConnection connection)
{
SqlConnection = connection;
connection.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler);
}
public SqlConnection SqlConnection { get; set; }
public string Message { get; set; }
void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e)
{
Message = e.Message;
}
}
Example of use :
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
var messageWrapper=new SqlInfoMessageWrapper(connection) ;
var ret = SqlHelper2.ExecuteNonQuery(connection, CommandType.Text, command, null);
messages+= $"{messageWrapper.Message} number of rows affected {ret} ";
}

Related

xamarin cannot conect to sql server

the application must connect directly to the sql server database and output data from the table
I wrote the following code:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System.Data.SqlClient;
namespace PrApp4
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
TextView textView1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
textView1 = FindViewById<TextView>(Resource.Id.textView1);
string ConString = "Data Source=COMP106-1\\SQLEXPRESS;Initial Catalog=AVTO_SALON;";
string SqlCom = "select * from Avto";
using (SqlConnection sqlCon = new SqlConnection(ConString)) {
sqlCon.Open();
SqlCommand cmd = new SqlCommand(SqlCom, sqlCon);
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
//await DisplayAlert("Уведомление", reader.GetString(1), "ОK");
textView1.Text = reader.GetString(1);
//textView2.Text = reader.GetString(3);
}
}
}
}
when you start the application, the following error appears:
cannot connect to sql server browser ensure sql server browser has been started

Perform SUM query in ADO.NET

I am getting following error
;expected
I am trying to find sum of column values in my webform.
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select SUM("AMOUNT DEPOSITED ") From MAIN_TABLE6";
Double amount = cmd.ExecuteScalar();
Label3.Text = amount.ToString();
}
Use brackets to enclose your columns in SQL Server.
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select SUM([AMOUNT DEPOSITED]) From MAIN_TABLE6";
Double amount = cmd.ExecuteScalar();
Label3.Text = amount.ToString();
}
I update-voted the answer by #ϻᴇᴛᴀʟ because he solved the problem with the brackets. However I like to see that database objects are closed and disposed. If database objects are kept local to the methods where they are used then using blocks accomplish this even if there is and error.
It is possible to pass the connection string directly to the constructor of the connection and pass the command text and connection to the constructor of the command. CommandType.Text is the default value so it is not necessary to set it.
I have opened the connection directly before the .Execute... and it is closed immediately after. The user interface is not updated until the connection is closed.
protected void Page_Load(object sender, EventArgs e)
{
double amount;
using (SqlConnection con = new SqlConnection("Your connection string"))
using (SqlCommand cmd = new SqlCommand("Select SUM([AMOUNT DEPOSITED]) From MAIN_TABLE6;", con))
{
con.Open();
amount = (double)cmd.ExecuteScalar();
}
Label3.Text = amount.ToString();
}

How do I check for duplicates and remove them on each data entry in SQL Server, WPF, C#?

I'm practicing SQL integration in C# by creating a Zoo Management app. Users can input a new name of Zoo to be listed on a ListBox. I want the app to check whether the new zoo is already listed or not (checking for duplicates), and if there is a duplicate, it will remove the newly added zoo.
I can't figure out the SQL query to do that.
Here I create a tiny simulation app to ask about the duplicates removing method.
Table name is TEST with just 2 columns Id and Name.
In the WPF there is a ListBox which lists all names, 2 buttons (Add and Remove names), and one TextBox to type in the want-to-be added name.
I've tried various methods and I just can't seem to get it to work.
public partial class MainWindow : Window
{
SqlConnection sqlConnection;
public MainWindow()
{
string connectionString = ConfigurationManager.ConnectionStrings["DeleteDuplicateTest.Properties.Settings.DB1ConnectionString"].ConnectionString;
sqlConnection = new SqlConnection(connectionString);
InitializeComponent();
ShowNames();
}
// This is where I got lost
public void CheckForDuplicates()
{
}
public void ShowNames()
{
string query ="select * from TEST";
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(query, sqlConnection);
using (sqlDataAdapter)
{
DataTable names = new DataTable();
sqlDataAdapter.Fill(names);
listNames.DisplayMemberPath = "Name";
listNames.SelectedValuePath = "Id";
listNames.ItemsSource = names.DefaultView;
}
}
private void Add_Click(object sender, RoutedEventArgs e)
{
if (myTextBox.Text != "")
{
string query = "Insert into TEST values (#Name)";
SqlCommand sqlCommand = new SqlCommand(query, sqlConnection);
sqlConnection.Open();
sqlCommand.Parameters.AddWithValue("#Name", myTextBox.Text);
sqlCommand.ExecuteScalar();
sqlConnection.Close();
ShowNames();
CheckForDuplicates();
}
}
private void Remove_Click(object sender, RoutedEventArgs e)
{
if (listNames.SelectedValue != null)
{
string query = "Delete from TEST where Id=#Name";
SqlCommand sqlCommand = new SqlCommand(query, sqlConnection);
sqlConnection.Open();
sqlCommand.Parameters.AddWithValue("#Name", listNames.SelectedValue);
sqlCommand.ExecuteScalar();
sqlConnection.Close();
ShowNames();
CheckForDuplicates();
}
}
}

SqlConnectionCommand ( CREATE DATABASE)

Does anyone know why the first code works but the second does not?
At the second I get exception (wrong syntax near #databaseName).
First Code
public void CreateDatabase(string databaseName)
{
string command = "CREATE DATABASE " + databaseName;
using (SqlConnection sqlConn = new SqlConnection(_sqlConnectionStringBuilder.ToString()))
{
sqlConn.Open();
using (SqlCommand sqlComm = new SqlCommand(command, sqlConn))
{
sqlComm.ExecuteNonQuery()
}
}
}
Second Code
public void CreateDatabase(string databaseName)
{
string command = "CREATE DATABASE #databaseName"; \\I tried both
string command = "CREATE DATABASE '#databaseName'"; \\I tried both
using (SqlConnection sqlConn = new SqlConnection(_sqlConnectionStringBuilder.ToString()))
{
sqlConn.Open();
using (SqlCommand sqlComm = new SqlCommand(command, sqlConn))
{
sqlComm.Parameters.Add(new SqlParameter(#"databaseName", databaseName));
sqlComm.ExecuteNonQuery()
}
}
}
In TSQL the general rule is you can't parameterize Data Definition Language (DDL) statements at all. And you can't use parameters in place of identifiers in Data Manipulation Language (DML) statements.

Readonly database MDF file. Windows app

can someone help me.
I've tried moving the MDF file around to different locations but I'm still unable to update the database. I'm using Windows 7.
Here's my code:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestDatabase
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
System.Data.SqlClient.SqlConnection con;
DataSet ds1;
System.Data.SqlClient.SqlDataAdapter da;
int MaxRows = 0;
int inc = 0;
private void Form1_Load(object sender, EventArgs e)
{
con = new System.Data.SqlClient.SqlConnection();
ds1 = new DataSet();
con.ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\rebdog\\AppData\\MyWorkers.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
con.Open();
string sql = "SELECT * From tblWorkers";
da = new System.Data.SqlClient.SqlDataAdapter(sql, con);
MessageBox.Show("database Open");
da.Fill(ds1, "Workers");
NavigateRecords();
MaxRows = ds1.Tables["Workers"].Rows.Count;
con.Close();
MessageBox.Show("database closed");
}
private void btnSave_Click(object sender, EventArgs e)
{
System.Data.SqlClient.SqlCommandBuilder cb;
cb = new System.Data.SqlClient.SqlCommandBuilder(da);
DataRow dRow = ds1.Tables["Workers"].NewRow();
dRow[1] = textBox1.Text;
dRow[2] = textBox2.Text;
dRow[3] = textBox3.Text;
ds1.Tables["Workers"].Rows.Add(dRow);
MaxRows = MaxRows + 1;
inc = MaxRows - 1;
da.Update(ds1,"Workers");
}
}
}
The code is from a tutorial, I need to get this working before I add a database to my project.
Thank you guys.
According to your code (in the connection string) the mdf file should be in
C:\Users\rebdog\AppData\MyWorkers.mdf
The connection is set up to use integrated security, meaning that it uses your windows login to access that database. So if you have problems accessing the database, it might be because it requires another user account, or because your user doesn't have read/write access to that folder.

Resources