Copy contents of one table to another table in a different Database - c#

I have a SQL table similar to (call it UserTable)
+--------+-----------+----------+
| UserId | FirstName | LastName |
+--------+-----------+----------+
| 123 | Bob | Smith |
| 456 | John | Doe |
+--------+-----------+----------+
On a different server I have a table (call it UserBackupTable)
+----------+--------+-----------+----------+
| Location | UserId | FirstName | LastName |
+----------+--------+-----------+----------+
| A | 123 | Bob | Smith |
| B | 456 | John | Doe |
+----------+--------+-----------+----------+
The two tables are identical except for the addition of one column (Location). I would like to backup/copy UserTable to UserBackupTable in a better way than
var dataToCopy = userDb.UserTable.Select(user => new UserBackup
{
Location = _location,
FirstName = user.FirstName,
LastName = user.LastName
}).ToList();
backupDb.UserBackups.AddRange(dataToCopy);
This works but isn't very efficient for me when I have 40+ columns to have to manually type out. These are database first models in case that is needed.

Can you not just do this at the database layer, rather than via an ORM, e.g.
SELECT *
INTO [backupDb].[dbo].[UserBackups]
FROM [dbo].[UserTable]
You'll need to modify the above depending how you do it, e.g. incrementally, or recreating the whole backup table each time depending on the size of your data (just make sure you drop the existing table and select into its replacement as part of a transaction) but you could just automate it via SQL Server Agent or something.
Note that SELECT INTO creates a new target table, so that wouldn't be suitable for an incremental backup approach.

Related

Merge data from two tables from different SQL Server database in C#

I have one central and two client database that have the same structure (identity id). The application allows users to merge data of selected tables from central db with one client db at a time.
For example:
[db_central].[table]:
+-------+-------+
| id | name |
+-------+-------+
| 1 | A |
| 2 | B |
| 3 | C |
+---------------+
[db_client_1].[table]:
+-------+-------+
| id | name |
+-------+-------+
| 3 | D |
+---------------+
[db_client_2].[table]:
+-------+-------+
| id | name |
+-------+-------+
| 3 | E |
+---------------+
Expected result after merging (twice):
[db_central].[table]:
+-------+-------+
| id | name |
+-------+-------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
+---------------+
Currently, I'm only able to load tables from database.
When user clicks "Manual Sync" button, the app will compare and merge data of selected tables from left to right database or vice versa.
If table doesn't exist, it will create the new one. If table does exist, it will compare and merge data but I don't know what is the best solution to accomplish this task.
Any suggestion would be appreciated.
This seems like a simple sql query (if the databases are on the same server, or if you have a linked server between them) using except...
insert into db_central // Target table
select name from db_client_1 // Source table
except
select name from db_central // Target table
If you have to do it in Linq, then it's very similar:
// Get the list of names to add
var newNames = dbContext.db_client_1.Select(e => e.name).Except(dbContext.db_central.Select(e => e.name));
// Convert the names to a list of entity objects and add them.
dbContext.db_central.Add(newNames.Select(e => new db_central { name = e.name });
dbContext.SaveChanges();
This is assuming you don't want duplicates in db_central
Ideally you should have two columns at table in Central Database
Primary key (with identity enabled)
ChildKey (Primary Key of Child databases)
Primary key column in central database will take care of ordering, and chiild column will give you primary key in respective database

Remove DataColumn from DataTable with Data

I have Datatable with Data. I called my postgres data base and get DataTable.
// get the new data from postgres
var dataTable = pg.GetDataTable("SELECT * FROM " + '"'+table+'"');
Now I need to remove specific Column. assume that there are 5 columns with data.
ID | Name | Address | Mobile | Home
_______________________________________________
1 | A |AAA | 123 | 345
2 | B |BBB | 234 | 456
3 | C |CCC | 345 | 567
So I need to remove "Home " DataColumn and Recreate this DataTable as following
ID | Name | Address | Mobile
____________________________________
1 | A |AAA | 123
2 | B |BBB | 234
3 | C |CCC | 345
How can I do this ?
Appreciate your comments.
Thanks
Just specify the columns you need explicitly rather than selecting unneeded columns and removing them afterwards:
SELECT "Id", "Name", "Address", "Mobile"
Using SELECT * is bad manners because it makes your contract with database unstable - should column configuration change you will get unpredictable result.
You just need to use the method DataTable.Columns.Remove(string name):
dataTable.Columns.Remove("Home");
Then the table doesn't contain this column anymore and all rows' data in this column is thrown away. However, omit this column in the first place and list the desired columns:
var dataTable = pg.GetDataTable("SELECT ID, Name, Address, Mobile FROM " + '"'+ table +'"');
Consider using
dataTable.Columns.Remove("ColumnName")
or
dataTable.Columns.RemoveAt(ColumnNumber)

SQL Theory Multiple References

i am designing a database and have theory problem, about which solution works better to run queries, to be faster on microsoft sql server or simply more relational.
GIVEN
Lets say, we have the following Tables:
Congress, Person, Session, Room, and much more.
Don't mind about the given names. These are just some basic standalone entities.
-----------------------------------------------------------------
| Congress | Person | Session | Room |
-----------------------------------------------------------------
| CongressID | PersonID | SessionID | RoomID |
| Name | Name | Name | Name |
| ... | ... | ... | ... |
-----------------------------------------------------------------
Additionally we have a table called "Right". Rights have a name and can define access to something like one or many of the basic entities. Each person can have those rights assigned.
So there are 2 more tables:
Right and PersonRight
---------------------------------
| Right | PersonRight |
---------------------------------
| RightID | PersonRightID |
| Name | PersonID |
| ... | RightID |
| ... | ... |
---------------------------------
SOUGHT-AFTER
Now there is only one thing missing. The way or table that represents the relations to the other entities. I know three different ways that all will work, but i don't have the deep experience to decide which one will be the best.
1. The relational way?
Upgrade: For every new entity, add a new table
Relation: Right 1 : N Entities
Pros: Adding new entities doesn't affect the others in any way, foreign keys to entities
Cons: Many tables with maybe redundant columns like CreatedDate or rowguid.
SQL Example::
select *
from Right r
left join RightCongress rc on r.RightID = rc.RightID
left join RightSession rs on r.RightID = rs.RightID
left join RightRoom ro on r.RightID = ro.RightID
left join Congress ec on rc.CongressID = ec.CongressID
left join Session es on rs.SessionID = es.SessionID
left join Room er on ro.RoomID = er.RoomID
-------------------------------------------------------
| RightCongress | RightSession | RightRoom |
-------------------------------------------------------
| RightCongressID | RightSessionID | RightRoomID |
| RightID | RightID | RightID |
| CongressID | SessionID | RoomID |
| ... | ... | ... |
-------------------------------------------------------
2. The column way?
2.1 The column way 1
Upgrade: For every new entity, add a new column to table "Right"
Relation: Right 1 : 1 Entities
Pros: No new table required, small statement, foreign keys to entities
Cons: Every new entity affect all other rows, only 1:1 relation possible, column count maybe confusing
SQL Example::
select *
from Right r
left join Congress ec on r.CongressID = ec.CongressID
left join Session es on r.SessionID = es.SessionID
left join Room er on r.RoomID = er.RoomID
-----------------
| Right |
-----------------
| RightID |
| Name |
| CongressID |
| SessionID |
| RoomID |
-----------------
2.2 The column way 2
Upgrade: For every new entity, add a new column to table "RightReference"
Relation: Right 1 : N Entities
Pros: 1:N relation, only one new table, small statement, foreign keys to entities
Cons: Every new entity affect all other rows, column count maybe confusing
SQL Example::
select *
from Right r
inner join RightReference rr on r.RightID on rr.RightID
left join Congress ec on rr.CongressID = ec.CongressID
left join Session es on rr.SessionID = es.SessionID
left join Room er on rr.RoomID = er.RoomID
---------------------------------------
| Right | RightReference |
---------------------------------------
| RightID | RightReferenceID |
| Name | RightID |
| ... | CongressID |
| ... | SessionID |
| ... | RoomID |
| ... | ... |
---------------------------------------
3. The reference way
Upgrade: For every new entity, add a new row to RightReference with the new ReferenceTypeID
Relation: Right 1 : N Entities
Pros: Only one new table and dynamic references
Cons: Anonymous references and have always to remember the indexes to build queries, no foreign keys to entities
Explanation: ReferenceID is the primary ID of the referenced entity/row, like of table Congress, Session and so on. So you can't suggest to which table it references. For that reason there is ReferenceTypeID. It points to a translation table called ReferenceType, where every table is stored with an unique id. Maybe it is possible to use the system method OBJECT_ID instead.
SQL Example::
select *
from Right r
inner join RightReference rr on r.RightID = rr.RightID
left join Congress ec on rr.ReferenceID = CongressID and rr.ReferenceType = 1
left join Session es on rr.ReferenceID = SessionID and rr.ReferenceType = 2
left join Room er on rr.ReferenceID = RoomID and rr.ReferenceType = 3
----------------------------------------------------------
| Right | RightReference | ReferenceType |
----------------------------------------------------------
| RightID | RightReferenceID | ReferenceTypeID |
| Name | RightID | Name |
| ... | ReferenceID | ... |
| ... | ReferenceTypeID | ... |
| ... | ... | ... |
----------------------------------------------------------
And now to all the sql experts.
What is the best or better lets say state of the art solution/way/approach to handle this task?
If you have other ways, please let me know.
What i am Looking for is: General Advantages and Disadavantages, SQL-Performance, implementation difficulties with EntityFramework and everything else you know or think about it.
Thanks!
Usually when dealing with relational databases, anything that requires a schema change is a no-no because you have to do potentially dangerous operations on your SQL server, update EF as well as whatever models you may be using and probably redeploy whatever application serves as the frontend for your database.
The SQL Solution
If you're OK with committing a no-no every time a new entity is added or are for some other reason tied to an RDBMS, you have two options:
If you care about your entity(Congress, Session, Room) table schema
Column way #2 is probably the best idea because it separates relational data from actual table data. Make a separate table for the relationships between entities and rights and put an index on every possible entityId. In your example you'd need indices on CongressId, SessionId and RoomId columns.
If you don't care about your entity table schema
Combine all entity tables into one large Entities table with an Id column and an XML column that contains all your actual entity info such as the type. Single relationship between Entities and rights and you're good.
The NoSQL Solution
If you can go this route, it would probably suit the flexible structure you're looking for much better. You will still need to update the code that accesses the document store but judging from your proposal that seems unavoidable unless you have some extraordinarily-flexible-but-error-prone code in place.
You don't need to do schema/EF updates every time a new entity type is added, and you don't need to worry about relationships. Your Person objects will have all their rights nested right inside and will be stored in the document store exactly that way.

How do a make a query to count which string appears the most in a certain column?

I'm making a program and I need to make a query to the database asking for the string that appears most often in a given column. In this example, its "stringONE".
----------------------------
| ID | Column (string) |
----------------------------
| 1 | stringONE |
----------------------------
| 2 | stringTWO |
----------------------------
| 3 | stringONE |
----------------------------
| 4 | stringONE |
----------------------------
Now I need to take the name of the string that appears the most and put it into a variable string, for example:
string most_appeared_string = sql.ExecuteScalar();
Also, what happens if there is no string that appears the most, rather 2 or more strings that appear the same amount of times, like this:
----------------------------
| ID | Column (string) |
----------------------------
| 1 | stringONE |
----------------------------
| 2 | stringTWO |
----------------------------
| 3 | stringTWO |
----------------------------
| 4 | stringONE |
----------------------------
Thanks ahead.
#KeithS
Do you have an sql-server version of the query because I'm getting some errors when trying it there. Here's a table example of what I'd like to do precisely.
------------------------------------------------
| ID | column1 (string) | author (string) |
------------------------------------------------
| 1 | string-ONE | John |
------------------------------------------------
| 2 | string-TWO | John |
------------------------------------------------
| 3 | string-ONE | Martin |
------------------------------------------------
| 4 | string-ONE | John |
------------------------------------------------
SELECT TOP (1) column1, COUNT(*) FROM table WHERE author='John' ORDER BY ID
It should return "string-ONE" since it appears the most (2) times for the author John. When trying the query in MS-SQL Management Studio though, this is the error I'm getting:
Column 'table.column1' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Nevermind the edit. Thank you.
This is a pretty easy query (in T-SQL at least):
select top 1 Column, Count(*) from Table group by Column order by Count(*) desc
ExecuteScalar, by an implementation detail, will return the string value because it's the first column of the only row in the result set, even though there are two columns. You could also use ExecuteReader to access the number of times that string occurs.
select top (1) SomeCol, count(*) as Row_Count
from YourTable
group by SomeCol
order by Row_Count desc
Also, what happens if there is no string that appears the most, rather
2 or more strings that appear the same amount of times, like this:
In that case, using the above query, you will get one arbitrary row. You can add with ties to get all rows that has the same highest value.
select top (1) with ties SomeCol, count(*) as Row_Count
from YourTable
group by SomeCol
order by Row_Count desc
SELECT max(counted) AS max_counted FROM (
SELECT count(*) AS counted FROM counter GROUP BY date
)
This could do the trick

Query tabels to sort sums across rows and count based on a value in LINQ

Here is my problem. i have 3-5 persons that is going to set a grade on one person and they use their own individual row to do so, and what I'm having trouble to do is to sum and average the grade from individual data across multiple rows on the same table.
in the select new statement i have made a pseudo answer of what i want
var users = from workRew in db.Reviews
select new
{
UserID = workRew.UserID.DistinctOfSomeSort
AvgGrade = workRew.Grade.Sum/CountOfSomeSort
};
Here i a illustration.
So if i have this table
| SomeID | UserID | Grade |
| 1 | 2 | 3 |
| 2 | 3 | 1 |
| 3 | 2 | 1 |
And this is the output i want from the LINQ query on the above (In theory ateast)
| UserID | AvgGrade |
| 2 | 2 |
| 3 | 1 |
EDIT: Simplified the whole case, to a great extent.
It should look something like this fragment:
group by user.UserID
select new
{
User = user.UserID
TotGradeCount = workRew.Grade.Sum()
Graders = workRew.Grade.Count()
}

Categories

Resources