c# LINQ find value in datareader - c#

This is my table on MySQL database :
+----------+--------+---------+
| UserName | Region | UsercIX |
+----------+--------+---------+
| a123456 | X410 | NULL |
| a123456 | X420 | 1 |
| a123456 | X430 | NULL |
| a123456 | X440 | 1 |
+----------+--------+---------+
The user a123456 is write enabled for X420 and X440 Region (UsercIX=1) and reading for X410 and X430 Region (UsercIX=NULL).
I need to find in this table -via LINQ or your suggestion- only values equals to 1 in the column UsercIX, because with DataReader extracting the first value of the column which is null.
Please an you help me ?
My code below
using (OdbcDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int UsercIX = Convert.ToInt32(reader["UsercIX"]); //IS NULL
}
}
}
Edit #01
using (OdbcDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
int UsercIX = reader.GetInt32(6);
}
}
}

May i suggest doing a try parse on the value?
int number;
bool success = Int32.TryParse((reader["UsercIX"], out number);
if (success)
{
// it worked, yay
}
else
{
// 😥
}

I think you should access the values in this way:
**SqlDataReader** reader = command.ExecuteReader();
int UsercIX = reader.GetInt32(2);
with in the while loop.
The colums start with 0
Eventually you run in an error when accesing Null-value then use a try() {} catch() {} structure to avoid this.
- Hope this helps!
Here is a complete example for mysql;
public void CreateMySqlDataReader(string mySelectQuery, MySqlConnection myConnection)
{
MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection);
myConnection.Open();
MMySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while(myReader.Read())
{
Console.WriteLine(myReader.GetString(0));
}
}
finally
{
myReader.Close();
myConnection.Close();
}
}

Related

DataGridView is not showing all columns from table

I have following table in my PostgreSQL database:
Table "public.ads"
Column | Type | Collation | Nullable | Default
----------------------+-----------------------------+-----------+----------+-----------------------------------
idad | integer | | not null | nextval('ads_idad_seq'::regclass)
uidowner | integer | | |
month | integer | | |
year | integer | | |
mileage | integer | | |
idmake | integer | | |
idmodel | integer | | |
idmotor | integer | | |
idbodytype | integer | | |
description | text | | |
createdat | timestamp without time zone | | not null |
optionalequipmentids | character varying[] | | |
photos | character varying[] | | |
price | integer | | |
generaldata | jsonb | | |
vehicledata | jsonb | | |
engineenvironment | jsonb | | |
conditionmaintenance | jsonb | | |
idfueltype | integer | | |
Indexes:
"ads_pk" PRIMARY KEY, btree (idad)
Foreign-key constraints:
"ads_idbodytype_fkey" FOREIGN KEY (idbodytype) REFERENCES bodytype(idbodytype) ON UPDATE CASCADE
"ads_idfueltype_fkey" FOREIGN KEY (idfueltype) REFERENCES fueltype(idfueltype) ON UPDATE CASCADE
"ads_idmake_fkey" FOREIGN KEY (idmake) REFERENCES make(idmake) ON UPDATE CASCADE
"ads_idmodel_fkey" FOREIGN KEY (idmodel) REFERENCES model(idmodel) ON UPDATE CASCADE
"ads_idmotor_fkey" FOREIGN KEY (idmotor) REFERENCES motor(idmotor) ON UPDATE CASCADE
I created method for filling DataGridView with data from table above, and here is the code part:
private void FillDataGridAds()
{
if (!connected) return;
string cmdString = string.Empty;
try
{
cmdString = "SELECT * FROM ads";
NpgsqlCommand command = new NpgsqlCommand(cmdString, conn);
NpgsqlDataAdapter da = new NpgsqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridAds.DataSource = dt.DefaultView;
}
catch (NpgsqlException ex)
{
textBox1.AppendText("PostgreSQL exception: " + ex.Message + Environment.NewLine);
}
catch (Exception ex)
{
textBox1.AppendText("Exception ex: " + ex.Message + Environment.NewLine);
}
}
Designer part of code of my dataGridAds
//
// dataGridAds
//
this.dataGridAds.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridAds.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridAds.ContextMenuStrip = this.contextMenuStrip1;
this.dataGridAds.Location = new System.Drawing.Point(9, 49);
this.dataGridAds.Name = "dataGridAds";
this.dataGridAds.RowHeadersWidth = 51;
this.dataGridAds.RowTemplate.Height = 29;
this.dataGridAds.Size = new System.Drawing.Size(1326, 549);
this.dataGridAds.TabIndex = 0;
this.dataGridAds.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridAds_CellEndEdit);
//
Problem:
For some reason when method for filling dataGridAds is triggered, dataGridAds is displaying all columns except optionalequipmentids and photos, so does anybody know where can be a problem, I was trying to figured out where problem might be, but unsuccessfully, have same issue with another tables in my appplication and want to fix as soon as possible, thank you all in advance.
The columns are both data-type character varying[] I assume that the columns in other tables with the same problem are the same data-type.
You could try using CAST. Does the following script with a nomnative SELECT with CASE for the problem columns work?
If CAST( ... AS VARCHAR(1000)) doesn't work you could also try
CAST( ... AS VARCHAR)
private void FillDataGridAds()
{
if (!connected) return;
string cmdString = string.Empty;
try
{
cmdString =
"SELECT
idad ,
uidowner ,
month ,
year ,
mileage ,
idmake ,
idmodel ,
idmotor ,
idbodytype ,
description ,
createdat ,
CAST( optionalequipmentids AS VARCHAR(1000)),
CAST( photos AS VARCHAR(1000)),
price ,
generaldata ,
vehicledata ,
engineenvironment ,
conditionmaintenance ,
idfueltype FROM ads";
NpgsqlCommand command = new NpgsqlCommand(cmdString, conn);
NpgsqlDataAdapter da = new NpgsqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridAds.DataSource = dt.DefaultView;
}
catch (NpgsqlException ex)
{
textBox1.AppendText("PostgreSQL exception: " + ex.Message + Environment.NewLine);
}
catch (Exception ex)
{
textBox1.AppendText("Exception ex: " + ex.Message + Environment.NewLine);
}
}

Run Stored Procedure and Check Value Exists or Not C#

I have this stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE ClientDelete
#clientid uniqueidentifier
AS
BEGIN
SET NOCOUNT ON;
UPDATE Clients SET enabled=1,editDate=GETUTCDATE() WHERE clientid=#clientid
END
Using this feature file:
Feature: ClientDelete
Scenario: Client Delete
Given a clean database
Given the following Clients table
| clientid | name | url | enabled | lastChangedBy | createDate | editDate |
| 1 | Client1 | https://test | true | test | 2000-01-01 | 2000-01-01 |
| 2 | Client2 | https://test | true | test | 2000-01-01 | 2000-01-01 |
When the "ClientDelete" stored procedure is run with the following parameters
| name | value |
| clientid | 11 |
Then the following is returned
| clientid | name | url | enabled | lastChangedBy | createDate | editDate |
| 1 | Client1 | https://test | false | test | 2000-01-01 | 2000-01-01 |
| 2 | Client2 | https://test | true | test | 2000-01-01 | 2000-01-01 |
C# Code:
[When(#"the ""(.*)"" stored procedure is run with the following parameters")]
public void WhenTheStoredProcedureIsRunWithTheFollowingParameters(string procName, Table table)
{
using (var con = CreateDBConnection())
{
using (var cmd = con.CreateCommand())
{
cmd.CommandText = procName;
cmd.CommandType = CommandType.StoredProcedure;
foreach (var row in table.Rows)
{
var param = cmd.CreateParameter();
param.ParameterName = row.Values.First();
if (param.ParameterName == "clientids")
{
param.SqlDbType = SqlDbType.Structured;
param.Value = new List<SqlDataRecord>()
{
ToSqlDataRecord(new Guid(row.Values.Last()))
};
}
else if (param.ParameterName == "docTypes")
{
param.SqlDbType = SqlDbType.Structured;
if (row.Values.Last() != "NULL")
{
param.Value = new List<SqlDataRecord>()
{
ToSqlDataRecord(row.Values.Last())
};
}
}
else if (row.Values.Last() != "NULL")
param.Value = row.Values.Last();
else
param.Value = DBNull.Value;
cmd.Parameters.Add(param);
}
var results = new DataTable();
using (var adapter = new SqlDataAdapter((SqlCommand)cmd))
{
adapter.Fill(results);
}
_context.Add("Results", results);
}
}
}
[Then(#"the following is returned")]
public void ThenTheFollowingIsReturned(Table table)
{
var results = _context.Get<DataTable>("Results");
Assert.AreEqual(table.Rows.Count, results.Rows.Count);
for (int i = 0; i < results.Rows.Count; i++)
{
var expectedRow = table.Rows[i];
var actualRow = results.Rows[i];
for (int j = 0; j < table.Header.Count; j++)
{
var name = table.Header.ElementAt(j);
var type = actualRow[name].GetType();
object expectedValue = expectedRow[name];
if (expectedValue.ToString().IsNullText())
expectedValue = null;
else if (type != typeof(DBNull))
expectedValue = TypeDescriptor.GetConverter(type).ConvertFromInvariantString(expectedRow[name]);
var actualValue = Convert.IsDBNull(actualRow[name]) ? null : actualRow[name];
Assert.AreEqual(expectedValue, actualValue, name);
}
}
}
#Then is not working as it's not returning anything from stored procedure so I want to check if the value updated or exists or not.
I have this too when and then used for multiple stored procedure which returns row data and is working fine, but does not work with add, delete, update.
Note: I need to do without adding output parameter to stored procedure.
After the update in your stored procedure add:
SELECT ##ROWCOUNT AS Result
This will return the number of rows affected by the previous update statement. You can then check in your C# code if the Result is > 0.
##ROWCOUNT documentation:
https://learn.microsoft.com/en-us/sql/t-sql/functions/rowcount-transact-sql?view=sql-server-ver15
You need to query the clients table again in your Then step. The DeleteClient stored procedure does not return anything, nor does it fill an output variable. Your only recourse is the query the clients table again in Then the following is returned. You can use the Table extension method CompareToSet(...) instead of doing the assertions manually yourself.

Updating rows on a table with condition

I'm trying to delete all the rows, starting from the bottom of the table using a condition, but when that conditions is met then i want it to stop updating the table and leave the rest as it was. Example, if the last entry on the table meets it, delete it, if the one after it does not meet the condition then stop there, and exite the loop.
Here's the code i got, but its deleting all the rows :
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("A atualizar dados");
bool check = true;
do
{
string connectionString = #"Data Source=.\wintouch;Initial Catalog=bbl;User ID=sa;Password=Pa$$w0rd";
string queryString = string.Empty;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
queryString = "DELETE FROM wgcdoccab
WHERE serie ='1' AND tipodoc ='FSS'
AND contribuinte ='999999990'
and datadoc = CONVERT(varchar(10),(dateadd(dd, -2, getdate())),120)"
SqlCommand command = new SqlCommand(queryString, connection);
//command.Connection.Open();
command.ExecuteNonQuery();
}
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
queryString = "SELECT * FROM wgcdoccab
WHERE serie !='1' and tipodoc !='FSS'
and contribuinte !='999999990'
and datadoc != CONVERT(varchar(10),(dateadd(dd, -1, getdate())),120) ";
using (SqlCommand command = new SqlCommand(queryString, connection))
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
check = true;
}
else
{
check = false;
MessageBox.Show("Dados Apagados com sucesso");
}
command.Connection.Close();
}
}
}
while (check);
Try something like this example:
DELETE
FROM tableName
WHERE ID >
(
SELECT MAX(ID)
FROM tableName
WHERE condition = false
)
For example, if you want to delete until a value is 4:
DELETE
FROM tableName
WHERE ID >
(
SELECT MAX(ID)
FROM tableName
WHERE tableName.Value = 4
)
If the table rows are:
|ID|Value|
| 1| 7|
| 2| 4|
Then the subselect will be 2 and no rows will be deleted. However, if the rows are:
|ID|Value|
| 1| 7|
| 2| 4|
| 3| 9|
| 4| 1|
Then the subselect will still return the ID of 2, and the last 2 rows will be deleted.

how to read last data of column using datareader in asp.net c#

I have one database and I want to get last value of column, and each time value will be updated after insertion
here is sample database,
ID | Customer_Name |new_Total | Total
--------------------------------------
1 | Mahesh | 100 | 200
2 | Mahesh | 400 | 600 (200+400)
3 | mahesh | 100 | 700 (600+100)
If i am getting you right you need to get last value of column i assume Total column.Here is you can read last value from database.
using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString()))
{
SqlCommand cmd = new SqlCommand("select Top 1 Total from tablename order by total desc", con);
SqlDataReader rdr;
con.Open();
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
int total;
int.TryParse(rdr["Total"].ToString(), out total);
}
}
You will get value in total variable and you can use it.

Reference data in SQLDataReader by column and rows or any alternative

I am running a stored procedure and the result is this format
+------+--------+-----+-------+
| ID | Resign | Sum | Count |
+------+--------+-----+-------+
| 1234 | 0 | 400 | 3 |
| 1234 | 1 | 800 | 4 |
+------+--------+-----+-------+
I tried this code to reference the values returned by the query but, it seem not working the way I want it
if (conn.State != ConnectionState.Open)
conn.Open();
SqlCommand sc = new SqlCommand();
sc.CommandText = "usp_GetResignPool";
sc.CommandType = CommandType.StoredProcedure;
sc.Connection = conn;
sc.Parameters.Add(AddParam(EndDate, "#EndDate"));
sc.Parameters.Add(AddParam(am_id, "#id"));
SqlDataReader reader;
reader = sc.ExecuteReader();
while (reader.Read())
{
if reader. // lost here
}
How can I do something like this. ↓
int resigned = 0, resign_count = 0, not_resigned = 0, notresign_count =0;
if (read["Resigned"] == 1)
{
resigned = read["sum"];
resign_count = read["count"];
}
else
{
not_resigned = read["sum"];
notresign_count = read["count"];
}
It is not important that I used SQLDataReader.
Edit: Real column names
ID Resigned sum count
--------- ----------- ---------------------- -----------
It didn't work because you don't have a column in your table named "Resigned", like you have when you are working with your SqlDataReader.
EDIT: I think the root of the problem is the way you are adding parameters. AddParam() is not the method you want to be using. Therefore, your result set is probably empty.
....
SqlCommand sc = new SqlCommand();
sc.CommandText = "usp_GetResignPool";
sc.CommandType = CommandType.StoredProcedure;
sc.Connection = conn;
sc.Parameters.AddWithValue("#EndDate", EndDate);
sc.Parameters.AddWithValue("id", am_id);
SqlDataReader reader;
reader = sc.ExecuteReader();
using (reader = sc.ExecuteReader())
{
while (reader.Read())
{
if (Convert.ToInt32(read["Resign"]) == 1)
{
resigned = Convert.ToInt32(read["Sum"]);
resign_count = Convert.ToInt32(read["Count"]);
}
else
{
not_resigned = Convert.ToInt32(read["Sum"]);
notresign_count = Convert.ToInt32(read["Count"]);
}
}
}
Notice how I changed your element indicator to "Resign". This needs to match the column that is returned in your dataset. Or, you could use a column number to get this, like so:
if (Convert.ToInt32(read[1]) == 1)
{
resigned = Convert.ToInt32(read[2]);
resign_count = read[3];
}
else
{
not_resigned = Convert.ToInt32(read[2]);
notresign_count = Convert.ToInt32(read[3]);
}
Also, keep in my that in every iteration or your while loop, you'll be overwriting the variables resigned, resign_count or not_resigned and notresign_count.
Would this work?
int resign = 0;
int not_resign = 0;
int resign_count = 0;
int not_resign_count = 0;
while (reader.Read())
{
if (Convert.ToInt32(reader["Resigned"]) == 1)
{
resign = Convert.ToInt32(reader["Sum"]);
resign_count = Convert.ToInt32(reader["Count"]);
}
else
{
not_resign = Convert.ToInt32(reader["Sum"]);
not_resign_count = Convert.ToInt32(reader["Count"]);
}
}
Can you post your query from the procedure?
Are the column names really "Sum" and "Count"?
There are reserved words, maybe you should try using "AS" and give other names to these to columns in the projection.

Categories