How to find column existence in data table in C#? - c#

I have problem. I have 2 queries in a stored procedure. Both run on certain condition if condition is true query one executes and returns 7 columns from 3 tables. If condition fail 2nd query returns 4 columns.
On front end I use a datatable to store query result. I assign values to textbox from datatable.
like
dt is data table name
Txt_name.Text=dt.Rows[0][6].ToString();
problem is that when 2nd query executes an error occurs. No columns exists at 6.
How I find dt has column at at index 6 or not?

Try this code
int indx = 6;
if(dt != null and dt.Columns.Count > indx)
{
Txt_name.Text=dt.Rows[0][indx].ToString();
}

You can check the colums count something like below:
int index = 6;
Txt_name.Text = dt.Columns.Count > index ? dt.Rows[0][index].ToString() : String.Empty;

Do you have access to modify the stored procedure? And also manage all resources that use this stored procedure? I would recommend that it return the same structure regardless of the result.
If there is a false result, just have the additional fields empty. You can achieve this with the COALESCE operator, which return a given value (as '' in case of empty string) if there is NULL (i.e. no records in joined table).
A function that behave different base on a fields-count will nearly
works as a Insurance to break the code in future. There will be a
magic number "6" which can make behavior of the if-else-clause invert
or always evaluate same result. If the stored procedure HAVE to return
different structures, evaluate true/false first an then call the
adequate stored procedure.

Related

How to check all multiple tables are updated?

While writing stored procedure, i have remove set no count on and check whether multiple rows are affected to check whether the table values are affected or not.
Then I have realized it will give bad performance.
Then I have implemented like ##rowcount.
But for checking one table this will be the good idea.
In stored procedure, I will update more than one table and delete more than one table.
How to return whether the values are updated/deleted in efficient way to the server side (where i will use .ExecuteScalar)?
Variant 1: Create trigger to log changes into table and after then get information from this table.
Variant 2: Use system variables ##rowcount to get information about rows effected.
Variant 3: Get information about rows effected and use your variable or output select or output statement which can store number of changed rows
Variant 4: Rewrite your code to pattern: int numberOfRecords = comm.ExecuteNonQuery();

How to access specific row in datareader?

I got OutOfMemoryException while download bulk reports . So I alter the code by using DataReader instead of DataSet .
How to achieve below code in DataReader because am helpless to use any DataTables & DataSet in my coding.
if (dataSet.Tables[0].Rows[i + 1]["Sr No"].ToString() == dataSet.Tables[0].Rows[i]["Sr No"].ToString())
I don't think you can access a row that has not been executed. The way I understand it, the DataReader returns row by row as it reads it from the Database.
You can try the following:
This will loop through each row that the DataReader will return in the dataset. Here you can check certain values/conditions, as follow:
while (dataReader.Read())
{
var value = dataReader["Sr No"].ToString();
//Your custom code here
}
Alternatively, you can also specify the column index, instead of the name, if you wish to do so, as follow:
while (dataReader.Read())
{
var value = dataReader.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
//Your custom code here
}
UPDATE
Why don't you place all the values read from the DataReader, into a list, and you can use this list afterwards for comparison between values if you need it.
Don't filter rows at the client level.
It's better to search for the right rows on the server, before they even reach the client, instead of fetching all the rows into the client and then filtering there. Simply incorporate your search criteria in the SQL query itself, and then fetch the rows that the server has already found for you.
Doing that:
Allows the server to use indexes and other database structures to identify the "interesting" rows potentially much faster than linearly searching through all rows.
You network connection between client and server will not be saturated by gazillion rows, most of which will be discarded at the end anyway.
May allow your client to deal with one row at a time in a simple way (e.g. using DbDataReader), as opposed to additional processing and/or storing multiple rows in memory (or even all rows, as you did).
In your particular case, looks like you'll need a self-join, or perhaps an analytic (aka. "window") function. Without knowing more about your database structure or what are you actually trying to accomplish, I can't know how your exact query is going to look like, bit it will probably be something along these lines:
-- Sample data...
CREATE TABLE T (
ID int PRIMARY KEY,
SR_NO int
);
INSERT INTO T VALUES
(1, 100),
(2, 101),
(3, 101),
(4, 100);
-- The actual query...
SELECT
*
FROM (
SELECT
*,
LEAD(SR_NO) OVER (ORDER BY ID) NEXT_SR_NO
FROM
T T1
) Q
WHERE
SR_NO = NEXT_SR_NO;
Result:
ID SR_NO NEXT_SR_NO
2 101 101
You can do this by using a do-while loop. Before checking the condition, the next row will be read and you can also access that row. Try this code :
do
{
your code
}
while(myreader.Read())

Error retrieving value of a column from data set

I am filling two tables in DataSet.while retrieving column from 2nd table in dataset i am getting error.Please help!
"There is no row at position 0."
Here is my code.
Stored Procedure
CREATE proc [dbo].[spDispatchDetails]
(
#JobNo int,
#Programme nvarchar(100)
)
as
begin
select ReceivedFrom,ChallanNo,ChallanDate,JobNo,ReceivingDate,LotNo from tblOrders where JobNo=#JobNo and OrderStatus='In Process'
select Quantity from tblProgramme where JobNo=#JobNo and Programme=#Programme
end
I am sharing image of my code.
probably it does not return any rows
you need to check the rows count in ds.Table[1] before you access rows in it.
Make sure that ds.Table[1].Rows.Count > 0
First check if SQL is returning rows, try executing the query manually. While debugging make sure the parameters are being sent correctly (the dropdown selected values)
The error is telling you that there is no rows in the second table. Ideally always check that the row count is greater than zero
On the beginning You should check if Your procedure returns any rows to ds.Tables[1], because this error is very typical to this situation.
Please check this part of Your procedure:
select Quantity from tblProgramme where JobNo=#JobNo and Programme=#Programme
and let us know if You get any rows.
The is no row at position 0
This issue means that there is no row that was returned from the execution of the SQL query for the second table in the dataset. For example, the Quantity value does not exist if the tblProgramme table where the JobNo and Programme match that values passed into the call.
One of the issues with ADO.NET is the amount of effort involved with checking types and row counts, etc.
To solve the issue you should check to ensure that the Table exists and that the Row count is at least 1, and even that the column exists too.
if (ds.Tables.Count == 2 && // Ensure two tables in the dataset
ds.Tables[1].Rows.Count > 0 && // Ensure second table has a row
ds.Tables[1].Rows[0]["Quantity"] != DBNull.Value) // Ensure value for Qty
{
// Then do something with it...
}
As a side note, I would suggest using an ORM as it removes nearly all of the issues that raw ADO.NET boilerplate code introduces.

check if a number from a column in a table is greater than 0

Sorry if this question is duplicate, but I have not found the answer. I want to check if a value of a column from a table is greater than 0, if not do something. The problem is that I do not know how to get the value from the table and check it.
My idea:
if(column table(Quantity) where ID=#ID >0)
{
Do something
}
I am using asp.net, C# and SQL.
Here is some of my code:
//This code is when an item is added to the table with the current id the number of the item is reduced by 1.
SqlCommand command = new SqlCommand("UPDATE Items SET Quantity=Quantity-1;
command.ExecuteNonQuery();
In the Items table I have the Quantity of the Item, so lets say 5 quantity of that specific item, and everytime that is added to the gridview is reduced by 1, I do not want it to be below 0. (Now with this code it goes below 0) I have the idea as I told you above but i do not know how to do it.
Anybody has an idea how to do it?
Just use WHERE in your query. Give me your detail story END to END.
Plus, if you want to alert an error if something happens on your query execution, you can doing by store the ExecuteNonQuery result into a variable.
Here is for your references
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery%28v=vs.110%29.aspx
Let me highlight some points here :
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
For all other types of statements, the return value is -1. If a rollback occurs, the return value is also -1.
From here, you can add some logical processing to what you do even the query return error result.
To get the value of the Quantity column after updating it, use the OUTPUT clause in your SQL statement, for example:
UPDATE <YOUR_TABLE> SET Quantity = Quantity - 1
OUTPUT INSERTED.Quantity
WHERE ID = <YOUR_ID>
Once your Quantity is being returned as 0, you can do whatever action you require in your software, such as showing a prompt if the user tries to decrease it any further.
There's more information on MSDN here: http://msdn.microsoft.com/en-us/library/ms177564.aspx
If you're not using SQL Server 2005 or later (which is required for OUTPUT), you could still write a simple Stored Procedure to do the same, e.g.
CREATE PROCEDURE DecreaseQuantity
#id int
AS
BEGIN
UPDATE <YOUR_TABLE>
SET Quantity = Quantity - 1
WHERE ID = #id
SELECT Quantity
FROM <YOUR_TABLE>
WHERE ID = #id
END
Just use WHERE clause within your UPDATE command:
SqlCommand command = new SqlCommand(
"UPDATE Items SET Quantity=Quantity-1 WHERE ID=#Id AND Quantity>0");
command.Parameters.AddWithValue("#Id", id);
int numberOfRecords = command.ExecuteNonQuery();
if (numberOfRecords==0)
throw new Exception("Error setting quantity.");
You can verify whether the quantity has been set by checking affected number of records, should be 1 if OK.
I would not recommend doing this kind of check in your application code.
For ensuring value ranges of columns in SQL there exists the construct of check constraints.
For example, if you want to ensure you won't ever have negative values (or zero) in a column you could add the following constraint
ALTER TABLE Items
ADD CONSTRAINT CK_Items_Quantity_Range CHECK (
Quantity > 0
)
Then if you do your UPDATE/INSERT you will receive an exception that you can react to in your application code.
Alternatively you could also use a trigger if you want some sql-action to be done when a column reaches a certain value.

select records between 2 bigint values fastest way - so use c# objects instead of querying database

Alright i have a table which contains 2 bigint column.
Example
val1 3213 12312
val2 13232 32322
.
.
.
select val from table where 3232 between col1 and col2
I need to use between operator to select single row data.
Now i tried dataview but it failed. Dataview is not supporting between operator.
like this
dwIpAddress.RowFilter = string.Format("{0} between CodeVal_1 and CodeVal_2", irParameter);
So which approach i can use ?
There are like 200000 data records.
Tried this and it is super slow
dwIpAddress.RowFilter = string.Format("CodeVal_1>= {0} and CodeVal_2<={0}", irParameter);
C# 4.0
have you tried
dwIpAddress.RowFilter = string.Format("CodeVal_1 <= {0} and {0} <= CodeVal_2", irParameter);
Also, since you mentioned you are using C# 4.0, there is the Entity Framework, which you could use instead of DataView. Something you may want to look into.
Also, if your DataView contains all records from your database table, then you may want to adjust your query so that it only gets the rows from the database that it needs, as opposed to returning all rows and then filtering in C# (if that's what you are doing)

Categories

Resources