Datatable Recors - c#

I have a datatable and it has 4 columns. My problem is some columns has same data, same date. I have to delete same data, same date. How can I delete dublicate data?
My Datatable:
In this table I have to delete 1 or 3 (Id) In code side with for or foreach loop. Because in the same date there is a same Isban.
Id Name Isban Date
1 A 123 09.09.2010
2 B 123 10.09.2010
3 C 123 09.09.2010
4 A 234 11.09.2010
5 B 342 12.09.2010
Thanks You
john

A standard way to do this is to run a select distinct query to insert the distinct records into a new table, delete the existing table, and then rename the new table to the previous table.
Edit: You can that you have to do this client-side.
One way is addressed here: Distinct in DataTable
Alternatively, loop through the table and store in a hash table each record; use the pair Isban/Date as the key and the record as the value. When you encounter a duplicate record it will already be in the hash table so you pass over it. Then, you can create a new data table from the records in the hash table.

If you DO have to do it in a loop, I would do it something like the following... Pre-query based on the minimum ID based on the given duplicate entitie elements, then delete for NOT being the minimum key
Select
FldDup1,
FldDup2,
min( IDKey ) as KeepThisID,
count(*) as TotalPerDupFields
from
YourTable
group by
FldDup1,
FldDup2
having
TotalPerDupFields > 1
In this case, you'll end up with a sample result of...
FldDup1 FldDup2 KeepThisID TotalPerDupFields
123 09.09.2010 1 2
as I was ignoring the 2nd column of "A", "B" and "C" as it didn't appear to be the indicator in your explanation of duplicates.
Then, I would isse a delete... via parameterized SQL-Delete query
Delete from YourTable
Where FldDup1 = ResultQuery.FldDup1
and FldDup2 = ResultQuery.FldDup2
and NOT IDKey = ResultQuery.KeepThisID

Related

Update all rows in sql table with unique random value without using primary key or unique key in c#

In my application, I fetch all tables in Database.
User will select table name and colum names to be masked.
Now i want to update sql table-columns with random generate string , which must be unique for each row without using primary key or unique key.
For example, In my Employeedb i have a table Employee.
Out of columns in Employee table, i want to mask data in name and city columns.
If table conatins 1000 rows, i want change name and city columns with 1000 unique values each. That means i want to update row by row.
Name Address City
Raghav flatno34 mumbai
Ranveer flatno23 chennai
This is orignal data
Name Adress City
Sbgha flatno34 mmjgujj
Lkhhvh flatno23 huughh
This is expected out
The table have primarykey sometimes.. There may be chances of not having primary key.
I have one more qn, I have this expected output in a datatable. Since i cannot predefine the table name and number of fields how will i write an update qry.
I think you will find my blog post entitled How to pre-populate a random strings pool very helpful for this requirement.
(Inspired by this SO answer from Martin Smith, to give credit where credit is due)
It describes an inline table valued user defined function that generates a table of random values, which you can use to update your data.
However, it does not guarantee uniqueness of these values. For that, you must use DISTINCT when selecting from it.
One problem you might encounter because of that is having a result with less values than you generated, but for 1,000 records per table as you wrote in the question it's probably not going to be a problem, since the function can generate up to 1,000,000 records each time you call it.
For the sake of completeness, I'll post the code here as well, but you should probably read the post at my blog.
Also, there's another version of this function in another blog post entitled A more controllable random string generator function for SQL Server - which gives you better control over the content of the random strings - i.e a string containing only numbers, or only lower digits.
The first thing you need to do is create a view that will generate a new guid for you, because this can't be done inside a user-defined function:
CREATE VIEW GuidGenerator
AS
SELECT Newid() As NewGuid
Then, the function code: (Note: this is the simpler version)
CREATE FUNCTION dbo.RandomStringGenerator
(
#Length int,
#Count int -- Note: up to 1,000,000 rows
)
RETURNS TABLE
AS
RETURN
-- An inline tally table with 1,000,000 rows
WITH E1(N) AS (SELECT N FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) V(N)), -- 10
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100
E3(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000
Tally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY ##SPID) FROM E3 a, E2 b) --1,000,000
SELECT TOP(#Count) (
SELECT TOP (#Length) CHAR(
-- create a random number from a guid using the GuidGenerator view, mod 3.
CASE Abs(Checksum(NewGuid)) % 3
WHEN 0 THEN 65 + Abs(Checksum(NewGuid)) % 26 -- Random upper case letter
WHEN 1 THEN 97 + Abs(Checksum(NewGuid)) % 26 -- Random lower case letter
ELSE 48 + Abs(Checksum(NewGuid)) % 10 -- Random digit
END
)
FROM Tally As t0
CROSS JOIN GuidGenerator
WHERE t0.n != -t1.n -- Needed for the subquery to get re-evaluated for each row
FOR XML PATH('')
) As RandomString
FROM Tally As t1
Then, you can use it like this to get a distinct random string:
SELECT DISTINCT RandomString
FROM dbo.RandomStringGenerator(50, 5000);

How to reorder auto increment column values, after deleting any row other than last row?

I want to know is there any SQL query for asp.net,c# that can just re arrange auto increment coloumn values..
eg.
deleting 2 in the table:
sno
1
2
3
4
does:
sno
1
3
4
but i want re-arrangement:
sno
1
2
3
Note:
Don't want to to the numbering manually
query to create table is like this:
CREATE TABLE uid (sno int IDENTITY(1,1) PRIMARY KEY, qpname nvarchar(500), mob int, tm int)
Let your table be named Parent and table that will hold the backup is called Backup. They should have identical columns.
INSERT INTO dbo.Backup
SELECT * FROM dbo.Parent
Now truncate the parent table
TRUNCATE TABLE dbo.Parent
Now you can just insert the data back using the first command and just reversing the table names.
Remember that this may not work in all cases. You may have On delete cascade on and if that is the case, then you would loose all data from other tables also which are referencing the parent table. I think that you should never use this is you are using any Foriegn Key reference on this table.
Following are the queries which should run 1 after other to get this functionality done. This can be easily achieved in C# by executing a generic ExecuteNonQuery().
DELETE FROM TBL1 WHERE sno = #sno;
UPDATE TBL1
SET sno = sno -1
WHERE sno > #sno;

Update a field 'version' into a table

I have this situation:
I have two tables:
Table A
Staging_Table A
Both tables contain those common columns:
Code
Description
Into Table A I also have a column Version which identifies the last version of corresponding column Code.
My problem is how to update the column Version once a new Description is stored for the same Code (I fill up the Staging_Table with a bulk Insert from C#. I have a flow of data that change once a week).
I need to insert the new row into Table A which contain the same Code, but a different Description, without deleting the old one.
I insert the rows from Staging table to table A with MINUS operation and I have this mechanism within a stored procedure because I also fill up the staging table with a Bulk Insert from C#.
The result I need to obtain is the following:
TABLE A:
Id Code Description Version End_date
-- ----------------- ------- --------
1 8585 Red Car 1 26-mag-2015
2 8585 Red Car RRRR 2 01-giu-2015
How can I do that?
I hope the issue is clear
If I understand correctly process work like that:
1. Data is loaded to staging table Staging_table_A
2. Data is inserted from Staging_table_A itno Table_A with additional column version.
I would do:
with cnt as (select count(*) c, code from Table_A group by code)
Insert into Table_A (select sta.*, nvl(cnt.c,0) + 1 as version
from Staging_table_A sta left outer join cnt on (sta.code = cnt.code));
This is based on condition that in Table_A versions contains no duplicates.

Get MAX id number from database table after deleting last record

I want to get a new row id for "products", for this I use MAX SQL command as follwing (the command is in insert new record button click event):
SqlCommand cmd = new SqlCommand("Select ISNULL(MAX(id)+1,0) from products", SqlCon);
the issue is when there are rows with IDs 10,11,12 (12 is MAX) and i delete id 12 record , i gets MAX+1 id 12 when the new id row is 13 ("id" field is PK with identity increment 1).
can i do it with other way?
example:
id prodect
-- -------
1 dog
2 cat
3 mouse
4 elefant
when i deletes row 4 i get MAX(id)+1 = 4 and i want to get 5 since this is the next row id.
I suspect the actual question is How can I find the ID of the row I just inserted so I can use it as a foreign key in related tables or in an image file name?
SQL Server since 2005 provides the OUTPUT clause in INSERT, UPDATE, DELETE statements that returns the values of the columns just inserted or modified. In the case of the insert statement, the syntax is:
insert into Products (Product)
OUTPUT inserted.ID
VALUES ('xxx')
This is a better option than the IDENT_CURRENT or SCOPE_IDENTITY values because it returns the values using a single statement and there is no ambiguity about what is returned:
IDENT_CURRENT may return a different value if multiple users are writing to the table outside a transaction
SCOPE_IDENTITY returns the last ID generated in a transaction, no matter the table
You can return more than one column:
insert into Products (Product)
OUTPUT inserted.ID, inserted.Product
VALUES ('xxx')
You can execute this statement with ExecuteScalar, if you return only one column or ExecuteReader, if you want to return more columns.
In the case of UPDATE or DELETE statements, the deleted table contains the deleted values and inserted contains the new values
Note ORMs like Entity Framework use such statements already to retrieve auto-generated IDs and update saved objects. In this case one only needs to read the ID property of the saved objects.
I will take a stab at what I think you are after. :)
If you include SELECT SCOPE_IDENTITY(); in your SQL you will get the ID you need:
INSERT INTO products (
* your fields *
)
VALUES (
* your values *
);
SELECT SCOPE_IDENTITY();
And then in your code you can have:
var Id = Convert.ToInt32(cmd.ExecuteScalar());
This will give you the id of the record you have inserted.
One possible solution could be that you don't delete the rows. You can add a flag and make it inactive/deleted. That way your row numbers will always be preserved and your code will give you the max Id.
I think the OP tries to tackle the wrong problem...
When you insert a new product into the products table, you should try to retrieve the new id directly with the scope_identity function as such (SQLServer!):
string sql = "insert into products(name) values('Yellow Cup'); SELECT SCOPE_IDENTITY();";
var sqlCommand = new SqlCommand(sql, conn);
var id = cSqlServer.ExecuteScalar();
Definitely MAX is not what anybody would use in this case. Closest solution would be to get recently used identity value and then increment it by 1 (in your case) or by seed value, whatever it is.
select ident_current('products') + 1
Caution - although this solves your purpose for now, beware that 'ident_current' will return you the identity value set by other sessions as well. In simple words, if there is some request/trigger/execution that causes id to be incremented even before your button click finishes then you you will get inserted_id and not deleted one.

Make a new table in DB to extract data from an already existing large table

I am working on a database which has around 2 year data and has around 100 million rows and 30 columns with values of every 10 seconds of different parameters. I want to create a new table which will have average of these data containing only 1 row for each date of data. The database has around 100 000 rows for each date.
Table name is process
and primary key is id
How can I do it because whenever I search for something in this already existing table it takes a long time to find out the required output.
is it possible to create a new table which will take the average of all the data(around 1 lakh rows) of a single date and put them in one row
You want something like:
CREATE TABLE averages AS
SELECT
date_trunc('day', data_capture_timestamp_column) AS day,
avg(col1) AS col1_avg,
avg(col2) AS col2_avg,
...
FROM my_table
GROUP BY 1;
The GROUP BY 1 says to GROUP the data by the first SELECT argument, which in this case is the date. An expression index on my_table( date_trunc('day', data_capture_timestamp_column)) is recommended.

Categories

Resources