C# & SQL Server: executing another query while Data Reader is opened - c#

I am intending to perform a call to ExecuteNonQuery() while the SqlDataReader is opened.
Code:
string commandString = "" //command string
using (SqlDataReader reader = cmd2.ExecuteReader())
{
while (reader.Read())
{
string temp = Convert.ToString(reader["RequestID"]);
string date;
using (SqlCommand cmd3 = new SqlCommand(commandString, con))
{
date = Convert.ToString(cmd3.ExecuteScalar());
}
}
}
I tried executing this but I got the error:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
There is already an open DataReader associated with this Command which must be closed first.
I have the MultipleActiveResultSets set to True in the connection string. May I know if it is possible to do it?

While MARS should work, it's usually not the best choice. Simply load the results of the first query into a DataTable and iterate the rows.
var dt = new DataTable();
using (SqlDataReader reader = cmd2.ExecuteReader())
{
dt.Load(reader);
}
foreach (DataRow row in dt.Rows)
{
string temp = Convert.ToString(row["RequestID"]);
string date;
SqlCommand cmd3 = new SqlCommand(commandString, con)
date = Convert.ToString(cmd3.ExecuteScalar());
}

You need to add MultipleActiveResultSets in your connection string, though you already added. Try below code that's executed successfully,
string conStr = "Data Source=DB_SERVER;Initial Catalog=DB_NAME;User Id=userId; Password=password;MultipleActiveResultSets=True";
using (SqlConnection con = new SqlConnection(conStr)) {
try {
con.Open();
string commandText = #"Select Id from Table1";
string commandText1 = #"Select CreatedDate FROM Table2 Where table1_Id = #table1_Id";
SqlCommand sqlCommand = new SqlCommand(commandText, con);
var dataReader = sqlCommand.ExecuteReader();
string date;
while (dataReader.Read()) {
var vId = dataReader["Id"].ToString();
var sqlCommand1 = new SqlCommand(commandText1, con);
sqlCommand1.Parameters.AddWithValue("#table1_Id", vId);
date= sqlCommand1.ExecuteScalar().ToString();
}
con.Close();
} catch (Exception ex) {
//Handle Exception
}
}

Related

Don't show insert tile second insert do in localDataBace

I want insert some data to localdatabace and insert is successfully done but don't show in my datagridview tile second insert do for debog it I Call Select All end of my insert and see the last insert don't show in it but whene i insert a next data , last data will be showing can every one help me pleas?
public void connect()
{
String conString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\hana\\documents\\visual studio 2017\\Projects\\Bank\\Bank\\Database.mdf;Integrated Security=True";
SqlConnection sql = new SqlConnection(conString);
String sqll = "Insert into TblBank (txtTodayDate" +
",txtSahebanHesab" +
",txtShobe" +
",txtShomareMoshtari" +
",txtShoareHesab" +
",cmbNoeHesab" +
",txtSarresid" +
")";
try
{
sql.Open();
SqlDataAdapter sda = new SqlDataAdapter(sqll, sql);
SqlCommand sc = new SqlCommand(sqll,sql);
sc.Parameters.AddWithValue("todayDate", new PersianDateTime(dtpTodayDate.the_date).ToString("yyyy/MM/dd"));
sc.Parameters.AddWithValue("sahebanHesab", txtSahebHesabName.Text);
sc.Parameters.AddWithValue("shobe", txtshobe.Text);
sc.Parameters.AddWithValue("shomareMoshtari", txtShomareMoshtari.Text);
sc.Parameters.AddWithValue("shoareHesab", txtShomareHesab.Text);
sc.Parameters.AddWithValue("noeHesab", cmbNoeHesab.SelectedIndex);
sc.Parameters.AddWithValue("sarresid", txtSarResidMah.Text);
sc.ExecuteNonQuery();
sql.Close();
select();
}
catch (Exception ex)
{
}
}
and select is
private void select()
{
String conString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\hana\\documents\\visual studio 2017\\Projects\\Bank\\Bank\\Database.mdf;Integrated Security=True";
SqlConnection cn = new SqlConnection(conString);
String sqlString = "SELECT * FROM TblBank Order BY Id desc ";
SqlConnection sql = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand(sqlString, cn);
try {
sql.Open();
SqlDataAdapter sa = new SqlDataAdapter(sqlString, sql);
using (SqlDataReader read = sa.SelectCommand.ExecuteReader())
{
if (read.Read())
{
DataTable dt = new DataTable();
dt.Load(read);
this.tblBankDataGridViewX.DataSource = dt;
}
}
sql.Close();
}
catch (Exception ex)
{
}
}
The DataReader.Read() method will iterate result set before DataTable.Load(). Because the DataReader is a forward-only stream, it has empty result set when DataTable.Load() executes and DataTable content is still empty while setting DataSource for DataGridView. Try DataReader.HasRows property to check result set availability:
using (SqlConnection cn = new SqlConnection(conString))
{
using (SqlCommand cmd = new SqlCommand(sqlString, cn))
{
try
{
cn.Open();
using (SqlDataReader read = cmd.ExecuteReader())
{
// check if the reader returns result set
if (read.HasRows)
{
DataTable dt = new DataTable();
dt.Load(read);
this.tblBankDataGridViewX.DataSource = dt;
}
}
}
catch (Exception ex)
{
// do something
}
}
}

How to return a string value from datatable in c#?

I am getting unable to store datatable value in string . How to return a string value of a data table? It gives an error while returning scalar value.
An exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll but was not handled in user code-- error in return statement
txtSalespersonName.Text = dl.GetStringValue("select top 1 [ContactPerson] from tbl_Companies where Company='" +companyname + "' order by id desc");
public string GetStringValue(string query)
{
DataTable dt = new DataTable();
try
{
string constr = ConfigurationManager.ConnectionStrings["KernelCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
}
}
}
}
catch (Exception ex)
{
// Response.Write(ex.Message);
}
return dt.Rows[1].ToString();
}
To answer your question, error is occurring because DataTable is zero indexed based and your query is returning just 1 value thus it is out of range. dt.Rows[0][0].ToString() will give you correct output.
But Since you are returning a single value from the query, I would suggest you to use ExecuteScalar instead like this:-
string ContactPerson = String.Empty;
string constr = ConfigurationManager.ConnectionStrings["KernelCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query,con))
{
ContactPerson = cmd.ExecuteScalar().ToString();
}
}
return ContactPerson;
Also, use parametrized query to avoid SQL Injection attack.
dt.Rows[1] returns the second DataRow in your table which is not exist since your query returns only one row. You can use it as;
return dt.Rows[0][0].ToString();
But don't use SqlDataAdapter if you only get one row. Use ExecuteScalar which is exactly what this for.
using (var con = new SqlConnection(constr))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = query;
con.Open();
return cmd.ExecuteScalar().ToString();
}
By the way, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.

C# MySqlConnector next query in the same connection

I have the following code:
string myConnection = "server=localhost;database=test;uid=test;password=test";
string query = "SELECT label_type, label, quantity FROM system_printserver WHERE print=0";
try
{
MySqlConnection myConn = new MySqlConnection(myConnection);
myConn.Open();
MySqlCommand command = new MySqlCommand(query, myConn);
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
MySqlDataReader myReader;
myReader = command.ExecuteReader();
while (myReader.Read()) {
orderNumber = myReader.GetString(1);
myReader.Close();
string queryOrder = "SELECT id_order, id_carrier FROM ps_orders WHERE id_order=28329";
MySqlCommand commandOrder = new MySqlCommand(queryOrder, myConn);
MySqlDataReader myReaderOrder;
myReaderOrder = commandOrder.ExecuteReader();
idCarrier = myReaderOrder.GetString(1);
printDocument1.Print();
}
I have a problem because the second query string queryOrder doesn't work. The query is Ok but variable "idCarrier" doesn't accept any value.
I don't believe you can attach another reader to a connection, when one is already open and processing records. You must retrieve all your records first, i.e. ToList() or Dataset, or use a secondary connection for the second reader.
To make your life easier, consider using Dapper or Linq2Db, two awesome micro-ORMs.
Try it like this:
using(var connection = new MySqlConnection("server=localhost;database=test;uid=test;password=test") {
connection.Open();
int orderNumber = 0;
using (var command = connection.CreateCommand()) {
command.CommandText = #"SELECT label_type, label, quantity FROM system_printserver WHERE print=0";
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
var reader = command.ExecuteReader();
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
if(reader.Read()) {
orderNumber = Convert.ToInt32(reader.GetString(1));
}
}
using(var command = connection.CreateCommand()) {
command.CommandText = string.format(#"SELECT id_order, id_carrier FROM ps_orders WHERE id_order={0}",orderNumber);
var reader = command.ExecuteReader();
if(reader.Read()){
printDocument1.Print();
return reader.GetString(1);
}
}
}

How can I get SQL result into a STRING variable?

I'm trying to get the SQL result in a C# string variable or string array. Is it possible? Do I need to use SqlDataReader in some way?
I'm very new to C# functions and all, used to work in PHP, so please give a working example if you can (If relevant I can already connect and access the database, insert and select.. I just don't know how to store the result in a string variable).
This isn't the single greatest example in history, as if you don't return any rows from the database you'll end up with an exception, but if you want to use a stored procedure from the database, rather than running a SELECT statement straight from your code, then this will allow you to return a string:
public string StringFromDatabase()
{
SqlConnection connection = null;
try
{
var dataSet = new DataSet();
connection = new SqlConnection("Your Connection String Goes Here");
connection.Open();
var command = new SqlCommand("Your Stored Procedure Name Goes Here", connection)
{
CommandType = CommandType.StoredProcedure
};
var dataAdapter = new SqlDataAdapter { SelectCommand = command };
dataAdapter.Fill(dataSet);
return dataSet.Tables[0].Rows[0]["Item"].ToString();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}
It can definitely be improved, but it would give you a starting point to work from if you want to go down a stored procedure route.
Try This:
SqlConnection con=new SqlConnection("/*connection string*/");
SqlCommand SelectCommand = new SqlCommand("SELECT email FROM table1", con);
SqlDataReader myreader;
con.Open();
myreader = SelectCommand.ExecuteReader();
List<String> lstEmails=new List<String>();
while (myreader.Read())
{
lstEmails.Add(myreader[0].ToString());
//strValue=myreader["email"].ToString();
//strValue=myreader.GetString(0);
}
con.Close();
accessing the Emails from list
lstEmails[0]->first email
lstEmails[1]->second email
...etc.,
You could use an SQL Data Reader:
string sql = "SELECT email FROM Table WHERE Field = #Parameter";
string variable;
using (var connection = new SqlConnection("Your Connection String"))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#Parameter", someValue);
connection.Open();
using (var reader = command.ExecuteReader())
{
//Check the reader has data:
if (reader.Read())
{
variable = reader.GetString(reader.GetOrdinal("Column"));
}
// If you need to use all rows returned use a loop:
while (reader.Read())
{
// Do something
}
}
}
Or you could use SqlCommand.ExecuteScalar()
string sql = "SELECT email FROM Table WHERE Field = #Parameter";
string variable;
using (var connection = new SqlConnection("Your Connection String"))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#Parameter", someValue);
connection.Open();
variable = (string)command.ExecuteScalar();
}
This May help you For MySQL
MySqlDataReader reader = mycommand.ExecuteReader();
while (reader.Read())
{
TextBox2.Text = reader.ToString();
}
For SQL
using (SqlCommand command = new SqlCommand("*SELECT QUERY HERE*", connection))
{
//
// Invoke ExecuteReader method.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
TextBox2.Text = reader.GetString(0);
}
}
Try this:
public string SaveStringSQL(string pQuery, string ConnectionString)
{
var connection = new Conexao(ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand(pQuery, connection.Connection);
var SavedString = (string)command.ExecuteScalar();
connection.Close();
return SavedString;
}
The ExecuteScalar function saves whatever type of data there is on your database - you just have to specify it.
Keep in mind that it can only save one line at a time.

How to get list of all database from sql server in a combobox using c#.net

I am entering the source name userid and password through the textbox and want the database list should be listed on the combo box so that all the four options sourcename, userid, password and databasename can be selected by the user to perform the connectivity
The databases are to be retrieve from other system as per the user. User will enter the IP, userid and password and they should get the database list in the combo box so that they can select the required database and perform the connectivity
private void frmConfig_Load(object sender, EventArgs e)
{
try
{
string Conn = "server=servername;User Id=userid;" + "pwd=******;";
con = new SqlConnection(Conn);
con.Open();
da = new SqlDataAdapter("SELECT * FROM sys.database", con);
cbSrc.Items.Add(da);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I am trying to do this but it is not generating any data
sys.databases
SELECT name
FROM sys.databases;
Edit:
I recommend using IDataReader, returning a List and caching the results. You can simply bind your drop down to the results and retrieve the same list from cache when needed.
public List<string> GetDatabaseList()
{
List<string> list = new List<string>();
// Open connection to the database
string conString = "server=xeon;uid=sa;pwd=manager; database=northwind";
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
// Set up a command with the given query and associate
// this with the current connection.
using (SqlCommand cmd = new SqlCommand("SELECT name from sys.databases", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
list.Add(dr[0].ToString());
}
}
}
}
return list;
}
First add following assemblies:
Microsoft.SqlServer.ConnectionInfo.dll
Microsoft.SqlServer.Management.Sdk.Sfc.dll
Microsoft.SqlServer.Smo.dll
from
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\
and then use below code:
var server = new Microsoft.SqlServer.Management.Smo.Server("Server name");
foreach (Database db in server.Databases) {
cboDBs.Items.Add(db.Name);
}
you can use on of the following queries:
EXEC sp_databases
SELECT * FROM sys.databases
Serge
Simply using GetSchema method:
using (SqlConnection connection = GetConnection())
{
connection.Open();
DataTable dtDatabases = connection.GetSchema("databases");
//Get database name using dtDatabases["database_name"]
}
using (var connection = new System.Data.SqlClient.SqlConnection("ConnectionString"))
{
connection.Open();
var command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = "SELECT name FROM master.sys.databases";
var adapter = new System.Data.SqlClient.SqlDataAdapter(command);
var dataset = new DataSet();
adapter.Fill(dataset);
DataTable dtDatabases = dataset.Tables[0];
}
How to get list of all database from sql server in a combobox using c# asp.net windows application
try
{
string Conn = "server=.;User Id=sa;" + "pwd=passs;";
SqlConnection con = new SqlConnection(Conn);
con.Open();
SqlCommand cmd = new SqlCommand();
// da = new SqlDataAdapter("SELECT * FROM sys.database", con);
cmd = new SqlCommand("SELECT name FROM sys.databases", con);
// comboBox1.Items.Add(cmd);
SqlDataReader dr;
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
//comboBox2.Items.Add(dr[0]);
comboBox1.Items.Add(dr[0]);
}
}
// .Items.Add(da);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Try this:
SqlConnection con = new SqlConnection(YourConnectionString);
SqlCommand cmd = new SqlCommand("SELECT name from sys.databases", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
cbSrc.Items.Add(dr[0].ToString());
}
con.Close();
or this:
DataSet ds = new DataSet();
SqlDataAdapter sqlda = new SqlDataAdapter("SELECT name from sys.databases", YourConnectionString);
sqlda.Fill(ds);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
cbSrc.Items.Add(ds.Tables[0].Rows[i][0].ToString());
}
public static List<string> GetAllDatabaseNamesByServerName(string ServerName, [Optional] string UserID, [Optional] string Password)
{
List<string> lstDatabaseNames = null;
try
{
lstDatabaseNames = new List<string>();
//string servername = System.Environment.MachineName;
string newConnString = string.Format("Data Source={0};", ServerName);
if (UserID == null)
{
newConnString += "Integrated Security = True;";
}
else
{
newConnString += string.Format("User Id ={0}; Password={1};", UserID, Password);
}
SqlConnection con = new SqlConnection(newConnString);
con.Open();
SqlCommand cmd = new SqlCommand("SELECT name FROM master.sys.databases", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
lstDatabaseNames.Add(row[0].ToString());
}
con.Close();
return lstDatabaseNames;
}
finally
{
}
}

Categories