System index out range exception C# - c#

I have the following code:
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeClock
{
class Company
{
DataTable rows = new DataTable();
public Company()
{
MySqlConnection connection = null;
try
{
string connectionString = TimeClock.Properties.Settings.Default.timeclockConnectionString;
connection = new MySqlConnection(connectionString);
connection.Open();
MySqlCommand command = new MySqlCommand("SELECT * FROM companies WHERE ID = #ID LIMIT 1", connection);
command.Parameters.AddWithValue("#ID", TimeClock.Properties.Settings.Default.CompanyID);
MySqlDataAdapter da = new MySqlDataAdapter(command);
da.Fill(rows);
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
Console.WriteLine(ex);
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}
public String getName()
{
DataRow row = rows.Rows[0];
return row["company_name"].ToString();
}
}
}
I know why I'm getting this error: say that no records were found in the database, the of course row[0] will no exist, hence the exception. But how do I deal with when there are no records to store in the Datatable? By the way, I'm quite new to C# and any input would be great; feel free to criticize.

Before you access a collection
DataRow row = rows.Rows[0];
you'll have to make sure that the item exists:
if(rows.Count > 0)
DataRow row = rows.Rows[0];
always

You must change getName function.
public String getName()
{
if (rows.Rows != null && rows.Rows.Count > 0)
{
DataRow row = rows.Rows[0];
return row["company_name"].ToString();
}
return string.Empty;
}

To read data from SQL I'm doing it like so:
using (SqlCommand SelectCommand = new SqlCommand(strbSelect.ToString()))
{
SelectCommand.Parameters.AddWithValue("Asset", AssetNumber);
SelectCommand.Parameters.AddWithValue("Subnumber", Subnumber);
SelectCommand.Connection = new SqlConnection(GetConnectionString());
SelectCommand.Connection.Open();
using (SqlDataReader Reader = SelectCommand.ExecuteReader())
{
if (Reader.HasRows)
{
while (Reader.Read())
{
if (Reader[0] != DBNull.Value)
{
ReturnValue = Reader.GetBoolean(0);
}
}
}
else
return false;
}
SelectCommand.Connection.Close();
}
StrbSelect is a StringBuilder.

Related

How to separate retrieved information from a select statement

I'm currently trying to get information from my sql database and separate it so it displays the information like so:
1)
2)
3)
etc...
Right now when I run the program the songs titles come back on their own line, but I want them numbered. I'm pulling song titles with a select statement and storing them in a string. How can I choose which title I want to put in my writeline? Is there a way for me to store it in a string array?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using System.Data;
namespace Databasetesting
{
class Play
{
//finding an artists
public static void FindArtist()
{
//servere connection
string cs = #"server=192.168.0.10;userid=dbsAdmin1903;password=password;database=Music_Mixer;port=8889";
MySqlConnection conn = null;
MySqlDataReader rdr = null;
//prompt for artist
string Art = PromptArtist();
try
{
//call in database
conn = new MySqlConnection(cs);
//open connection
conn.Open();
//Statement
String cmdText = "SELECT song_title FROM songs WHERE artist = #uI LIMIT 15";
//make a new command
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
//binding
cmd.Parameters.AddWithValue("#uI", Art);
//make reader = to new command
rdr = cmd.ExecuteReader();
//if something is not found
while (!rdr.HasRows)
{
Console.WriteLine("\r\nSorry, we could find that Artist.");
Console.WriteLine("Would you like to try again?!");
Menu.menu();
}
//run the reader and display to user
Console.Clear();
Console.WriteLine($"Here are 15 songs by {Art}!");
while (rdr.Read())
{
//store song titles and display to user
string Songs;
Songs = rdr["Song_title"].ToString();
Console.WriteLine (Songs);
}
//run the play again method
Console.Write("Press ENTER to continue...");
Console.ReadLine();
Console.WriteLine("What would you like to do?");
Menu.again();
}
catch (MySqlException er)
{
Console.WriteLine(er);
}
finally
{
if (conn != null)
{
conn.Close();
}
Console.ReadLine();
}
}
}
If I undestood correct
List<string> songsTitles = new List<string>();
while (rdr.Read())
{
//store song titles and display to user
string song = rdr["Song_title"].ToString();
Console.WriteLine(song);
songsTitles.Add(song);
}
var numberedSongs = songsTitles.Select((obj, index) => new {Index = index, Obj = obj}).ToArray();
string[] numberedSongsString = songsTitles.Select((obj, index) => $"{index}) {obj}").ToArray();
You can use an auxiliar datatable, something like this:
DataTable dt = new DataTable();
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
dt.Load(cmd.ExecuteReader());
if(dt.Rows.Count != 15){
//error code
}else{
foreach(DataRow row in dt.Rows){
Console.WriteLine(row["Song_title"].ToString());
}
}

Oracle Query is not being executed

I'm trying to retrieve values from an Oracle database using C# WebMethod, ajax and JavaScript, I have another page with exactly all the same functions and methods (using MSSQL Database) and work fine, but now I want to do it with Oracle. This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Oracle.DataAccess.Client;
using System.Data;
using System.Configuration;
/// <summary>
/// Summary description for OracleConexion
/// </summary>
public class OracleConexion
{
OracleConnection conn;
DataTable dt;
OracleDataAdapter da;
OracleDataReader dr;
DataSet ds;
OracleCommand cmd;
public OracleConexion()
{
conn = new OracleConnection("Data Source = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = ***.**.**.***)(PORT = ****)))(CONNECT_DATA = (SERVER = DEDICATED)(SID = *****))); User Id = *****; Password = ****;");
}
private void Open()
{
string canConnect;
try
{
conn.Open();
canConnect = "Nice";
}
catch (Exception ex)
{
//Code Updated
canConnect = ex.Message.ToString();
}
Console.Write(canConnect);
}
private void Close()
{
try
{
conn.Close();
}
catch (Exception ex)
{
}
}
public DataTable ConsultarTablas(string opcion)
{
dt = new DataTable();
ds = new DataSet();
string sql = "";
switch (opcion)
{
case "Datos":
sql = "Select Component as Result from BOM_Explosion where TOP_MATERIAL = '-FHN7092A-EF' and ROWNUM <= 5;";
break;
}
try
{
Open();
OracleDataAdapter da = new OracleDataAdapter(sql, conn);
da.Fill(ds);
dt = ds.Tables[0];
}
catch (Exception ex)
{
}
finally
{
Close();
}
return dt;
}
}
And this is my WebMethod
[WebMethod]
public string ObtenerDatosNumeroParte()
{
DataTable dt = new DataTable();
dt = conn.ConsultarTablas("Datos");
Ticket ti;
List<Ticket> lista = new List<Ticket>();
for (int i = 0; i < dt.Rows.Count; i++)
{
ti = new Ticket();
ti.Vs = dt.Rows[i]["Result"].ToString();
lista.Add(ti);
ti = null;
}
JavaScriptSerializer js = new JavaScriptSerializer();
string lineas = js.Serialize(lista);
return lineas;
}
Testing it seems like my code do not execute my query and my List always is null, what I'm doing wrong and what can I do to solve it?
Update
Using my string canConnect I get ORA-6413: Connection not open.

get all row and column data using SELECT - C#

I'm trying to get all data from an SQL table and store it in a List using the C# programming language.
the SQL statement I'm using is:
private string cmdShowEmployees = "SELECT * FROM Employees;";
This is being used in the same class as a function
public List<string> showAllIdData()
{
List<string> id = new List<string>();
using (sqlConnection = getSqlConnection())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = cmdShowEmployees;
SqlDataReader reader = sqlCommand.ExecuteReader();
while (reader.Read()) {
id.Add(reader[0].ToString());
}
return id;
}
}
and here
public List<string> showAllActiveData()
{
List<string> active = new List<string>();
using (sqlConnection = getSqlConnection())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = cmdShowEmployees;
SqlDataReader reader = sqlCommand.ExecuteReader();
while (reader.Read()) {
active.Add(reader[1].ToString());
}
return active;
}
I would have to create 9 more functions this way in order to get all the data out of the Employees table. This seems very inefficient and I was wondering if there was a more elegant way to do this.
I know using an adapter is one way to do it but I don't think it is possible to convert a filled adapter to a list, list list etc.
SqlDataAdapter adapter = sqlDataCollection.getAdapter();
DataSet dataset = new DataSet();
adapter.Fill(dataset, "idEmployees");
dataGridView1.DataSource = dataset;
dataGridView1.DataMember = "idEmployees";
Any ideas?
If you must use the reader in this way, why not create an object which holds the table row data.
public class SomeComplexItem
{
public string SomeColumnValue { get; set;}
public string SomeColumnValue2 { get; set;}
public string SomeColumnValue3 { get; set;}
public string SomeColumnValue4 { get; set;}
}
That way you can loop through with your reader as follows:
public List<SomeComplexItem> showAllActiveData()
{
List<SomeComplexItem> active = new List<SomeComplexItem>();
using (sqlConnection = getSqlConnection())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = cmdShowEmployees;
SqlDataReader reader = sqlCommand.ExecuteReader();
while (reader.Read())
{
var someComplexItem = new SomeComplexItem();
someComplexItem.SomeColumnValue = reader[1].ToString();
someComplexItem.SomeColumnValue2 = reader[2].ToString();
someComplexItem.SomeColumnValue3 = reader[3].ToString();
active.Add(someComplexItem);
}
return active;
}
You could use two select statements to populate two List<string> as shown in the example below where the key between reads is reader.NextResult();.
The database used is the standard Microsoft NorthWind database.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
namespace SQL_Server_TwoList
{
public class DataOperations
{
public List<string> Titles { get; set; }
public List<string> Names { get; set; }
/// <summary>
/// Trigger code to load two list above
/// </summary>
public DataOperations()
{
Titles = new List<string>();
Names = new List<string>();
}
public bool LoadData()
{
try
{
using (SqlConnection cn = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
string commandText = #"
SELECT [TitleOfCourtesy] + ' ' + [LastName] + ' ' + [FirstName] As FullName FROM [NORTHWND.MDF].[dbo].[Employees];
SELECT DISTINCT [Title] FROM [NORTHWND.MDF].[dbo].[Employees];";
using (SqlCommand cmd = new SqlCommand(commandText, cn))
{
cn.Open();
SqlDataReader reader = cmd.ExecuteReader();
// get results into first list from first select
if (reader.HasRows)
{
while (reader.Read())
{
Names.Add(reader.GetString(0));
}
// move on to second select
reader.NextResult();
// get results into first list from first select
if (reader.HasRows)
{
while (reader.Read())
{
Titles.Add(reader.GetString(0));
}
}
}
}
}
return true;
}
catch (Exception)
{
return false;
}
}
}
}
Form code
namespace SQL_Server_TwoList
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DataOperations dataOps = new DataOperations();
if (dataOps.LoadData())
{
listBox1.DataSource = dataOps.Names;
listBox2.DataSource = dataOps.Titles;
}
}
}
}
You could always add it all to a dataset or datatable instead of looping through using datareader to add to an array, dataset allows you to access data in similar way to array anyway.
Connstr = "Data Source = " + SelectedIP + "; Initial Catalog = " + dbName + "; User ID = " + txtUsername.Text +"; Password = "+ txtPassword.Text +"";
conn = new SqlConnection(Connstr);
try
{
string contents = "SELECT * FROM ..."
conn.Open();
SqlDataAdapter da_1 = new SqlDataAdapter(contents, conn); //create command using contents of sql file
da_1.SelectCommand.CommandTimeout = 120; //set timeout in seconds
DataSet ds_1 = new DataSet(); //create dataset to hold any errors that are rturned from the database
try
{
//manipulate database
da_1.Fill(ds_1);
if (ds_1.Tables[0].Rows.Count > 0) //loop through all rows of dataset
{
for (int i = 0; i < ds_1.Tables[0].Rows.Count; i++)
{
//rows[rownumber][column number/ "columnName"]
Console.Write(ds_1.Tables[0].Rows[i][0].ToString() + " ");
}
}
}
catch(Exception err)
{}
conn.Close();
}
catch(Exception ex)
{}

Properly displaying an array using C#

Below is my code. I'm trying to display some data as an array drawing from a SQL server. The problem is when I get to foreach I can't seem to get it to display the data correctly and it either keep repeating the data or just doesn't display it. I apologize if this questions seems basic I am a noob to programming and from what I have have researched I think I need to change my writeline to a write and potentially do another for loop....just not entirely sure any suggestions would help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
string connection = "Data Source=INIWS64-04;Initial Catalog=INEW18_2013;Network Library=DBMSSOCN; User ID=recordsadmin;Password=security";
DataTable table = new DataTable();
string Sql = "";
Sql = "select * from qryEDocRequest order by Request_ID";
using (SqlConnection conn = new SqlConnection(connection))
{
try
{
conn.Open();
SqlCommand comm = new SqlCommand(Sql, conn);
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
{
adapter.Fill(table);
}
for (int i = 0; i < table.Rows.Count; ++i)
{
DataRow row = table.Rows[i];
for (int w = 0; w < table.Columns.Count; ++w)
{
StringBuilder array = new StringBuilder();
foreach (Char Item in row.ItemArray.ToString())
{
array.Append(Item + ",");
}
Console.WriteLine(array);
}
}
}
catch (Exception Test)
{
throw Test;
}
}
}
}
}
Here is a lot easier way to do what you are trying to do:
using (SqlDataAdapter adapter = new SqlDataAdapter(comm))
{
adapter.Fill(table);
}
foreach(var row in table.Rows)
{
Console.WriteLine(String.Join(",", row.ItemArray));
}
based off of your response I was able to resolve using the foreach as follows
{
adapter.Fill(table);
}
foreach (DataRow row in table.Rows)
{
Console.WriteLine(String.Join(",", row.ItemArray));
}
Thanks so much this was the simplest way

C# return mysql number of rows

If in php we can do something like where $result is some query:
$result = mysql_query("SELECT * FROM student");
if (mysql_num_rows($results) !==0)
{
//do operation.
}
else
echo "no data found in databasae";
What is equivalent to this if I want to do this in C# language?please advise.
I have Created a full Console application using mysql. In your select query you are querying the whole table which is a bad idea. use limit to get only one result - this should be enough to determine if there are any rows in the table.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql;
using MySql.Data.MySqlClient;
namespace ConsoleApplication29
{
class Program
{
static void Main(string[] args)
{
if (AnyRows())
{
Console.WriteLine("There are rows in the database");
}
else
Console.WriteLine("no data found in database");
//This will pause the output so you can view the results. Otherwise you will see the dos screen open then close.
Console.Read();
}
//This is the Methos to call
public static bool AnyRows()
{
string connectionString = "Server=localhost;Database=test;Uid=root;Pwd=yourpassword;";
//Wrap this is using clause so you don't have to call connection close
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
string query = "select * from mytable limit 1";
using (MySqlCommand command = new MySqlCommand(query, connection))
{
MySqlDataReader reader = command.ExecuteReader();
return reader.HasRows;
}
}
}
}
}
assuming "results" is of type int
if(results != 0)
{
//do operation
}
else
{
Console.WriteLine("..."); //or output elsewhere
}
c# if else
add a reference to linq, and it gets really easy
var result = SomeDatabaseCall();
if (result.Any()){
// do something
}
if you want to filter the results even further, you can do that inside the Any
var result = SomeDatabaseCall();
if (result.Any(r => r.ID == SomeID)){ // ID can be replaced with any properties in your return model
// do something
}
I got the solution. It is actually very simple. BTW thanks for those who helping. This is the solution:
class DBConnect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
public DBConnect()
{
Initialize();
}
private void Initialize()
{
server = "your_server";
database = "your_db";
uid = "usr";
password = "pwd";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
}
//open connection to database
private bool OpenConnection()
{
try
{
connection.Open();
return true;
}
catch (MySqlException ex)
{
//When handling errors, you can your application's response based on the error number.
//The two most common error numbers when connecting are as follows:
//0: Cannot connect to server.
//1045: Invalid user name and/or password.
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact administrator");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
//Close connection
private bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
public void Select()
{
string query = "SELECT * FROM table";
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data in the database
if (dataReader.HasRows == true)
{
while (dataReader.Read())
{
//do retrieve data
}
}else
{
MessageBox.Show("There's no recods in the database");
}
}
}
}
It's best to use SELECT 1 instead of grabbing unnecessary data from the database to simply check for the existence of rows.
public static bool IsTableEmpty(string tableName)
{
string cs = "Server=localhost;Database=test;Uid=root;Pwd=sesame;";
using (var conn = new MySqlConnection(cs))
{
conn.Open();
string sql = string.Format("SELECT 1 FROM {0}", tableName);
using (var cmd = new MySqlCommand(sql, conn))
{
using (var reader = cmd.ExecuteReader())
{
return !reader.HasRows;
}
}
}
}
If you want to get the row count, then you'll need something like:
public static int GetTableRowCount(string tableName)
{
string cs = "Server=localhost;Database=test;Uid=root;Pwd=sesame;";
using (var conn = new MySqlConnection(cs))
{
conn.Open();
string sql = string.Format("SELECT COUNT(*) FROM {0}", tableName);
using (var cmd = new MySqlCommand(sql, conn))
{
return Convert.ToInt32(cmd.ExecuteScalar());
}
}
}

Categories

Resources