Insert from One MS Access database to Another MS Access database - c#

I have to take the data from MS Access DB to another.
This was insert statement used
cmd.CommandText = #"Insert Into [MS Access;PWD=pw;DATABASE=" + currentDBPath + #"].[Orders] Select * FROM [Orders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";
This statement works fine. But some one started to enter the data directly to target database and also in the source. This created duplicated records. Now I want to copy those orders from source which are not in the target DB's table.

Assuming Orders table has a primary key named IDOrers, you must bring both tables to one DB, so you can compare data.
Easy option: have in Sours DB a link to [Orders] on Destination DB, named OrdersDest. In that case you create on destination a query of missing orders, named MissingOrders :
SELECT Orders.* FROM Orders LEFT JOIN OrdersDest ON OrdersDest.IDOrders = Orders.IDOrders WHERE OrdersDest.IDOrders Is Null
Your Command will now look like this:
cmd.CommandText = #"Insert Into [MS Access;PWD=pw;DATABASE=" + currentDBPath + #"].[Orders] Select * FROM [MissingOrders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";
You could also pass the data through this linked table:
cmd.CommandText = #"Insert Into [OrdersDest] Select * FROM [MissingOrders] where OrderDate>=#" + from.ToShortDateString() + "# and OrderDate <=#" + to.ToShortDateString() + "# and IsCustomer=Yes ";

I didn't find any solution to what I was looking for in my question , So I decided to just delete the duplicated data in destination database.
I used the below statement to delete the data ,
Delete * from Orders where AutoOrderID in (SELECT Orders.AutoOrderID FROM Orders Inner JOIN OrdersSource ON OrdersSource .OrderId = Orders.OrderId and OrdersSource .OrderDate=Orders.OrderDate);

Related

How to copy data from two different table and insert fetched records into another table

I am trying to insert data in my table which have 3 feild
(1) sendReqID type int(PK)
(2) RequestID type int (FK from table Request)
(3) DonorID type int (FK table Donor)
I know how to copy data from one table and insert into another table but I want to know how to insert data in table, when we have to extract values from two different tables. Following is my code which I am trying and unable to insert data into my table.
public void Req_SendID()
{
SqlConnection MySQL = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ToString());
string copy = "insert into Send_Request(RequestID,DonorID) Select RequestID,DonorID from RequestID and DonorID from Donor where R_City='" + Session["BGroup"] + "' and" + "D_City='" + Session["city"] + "'";
SqlCommand com = new SqlCommand(copy, MySQL);
MySQL.Open();
com.ExecuteNonQuery();
MySQL.Close();
}
Please Help thanks in advance.
You need to join on the two tables...
insert into Send_Request(RequestID,DonorID)
Select r.RequestID, d.DonorID
from RequestID r inner join Donor d ON r.R_City = d.D_City
where R_City='" + Session["BGroup"] + "' and " + "D_City='" + Session["city"] + "'"
I'm assuming the relationship is as above. However, consider SQL Injection attacks and look to parametrize your query.
EDIT: Using Parameterized Query
var requestCity = Session["BGroup"].ToString();
var donorCity = Session["city"].ToString();
"insert into Send_Request(RequestID,DonorID)
Select r.RequestID, d.DonorID
from RequestID r inner join Donor d ON r.R_City = d.D_City
where R_City=#RequestCity and D_City=#DonorCity"
SqlCommand com = new SqlCommand(copy, MySQL);
com.Parameters.Add("#RequestCity", requestCity);
com.Parameters.Add("#DonorCity", donorCity);
....
However, I just saw your comment that there is no relationship between the tables, so the actual query above would be incorrect.

How to pass absolute database name,server name as parameter?

I have a requirement where I need to select data from database DB1 and insert into database DB2.
update [Server1\SQLEXPRESS].[DB1].dbo.table1
set CName = (select CName
from [Server2\SQLEXPRESS].[DB2].dbo.table1
where CID = 3)
So above script is working fine.
Now I want to pass
[Server1\SQLEXPRESS].[DB1]
[Server2\SQLEXPRESS].[DB2]
as parameters, because the server name and database can be different in real time environment.
Can you tell me how to achieve below goal?
create procedure
#CID numeric,
#ServerName1 serverDataType,
#ServerName2 serverDataType,
#DBName1 dbDataType,
#DbName2 dbDataType
as
update #ServerName1.#DBName1.dbo.table1
set CName = (select CName
from #ServerName2.#DBName2.dbo.table1
where CID = #CID)
Try this something in this fashion:
DECLARE #ServerName1 varchar(max) = 'MyServer'
DECLARE #DB1 varchar(max) = 'MyDB'
EXEC('update ' + #ServerName1 + '.' + DB1 + '.dbo.table1
set CName= (select CName from ' + #ServerName1 + '.' + DB1 +
'.dbo.table1' where CID ='+ #CID)

Nested Insert Into Errors

I've created this Insert Into SQL query, it takes information from the table lessons where the text box containing the lesson ID matches with any of the lessons. I have tested this Query works as it returns the correct values to a datagrid view in.
The second part of the query is supposed to get the student ID and Student Name from the text box that the user has input information. Then transfer this into the Less/Stud table.
This table has a the following Columns
Lesson Name Lesson ID Student ID Student Name Optional?
I do not need to worry about the Optional column as that is a check box not needed yet, below is the current query that doesnt work. It returns the following errors:
Incorrect Syntax near '/'
Incorrect Syntax near 'Test Student Name'
The second error within the ' ' always contains the information from the student name text box.
INSERT INTO Less/Stud ([LessonName],[Lesson ID],[Student ID],[Student Name])
SELECT LessonName, LessonID
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "'
AND (SELECT [Student ID], [StudentName]
'" + txtStuId.Text + "', '" + txtName.Text + "' "
You need to put all four columns being inserted in the outer select:
INSERT INTO Less/Stud ([LessonName],[Lesson ID],[Student ID],[Student Name])
SELECT LessonName, LessonID, '" + txtStuId.Text + "', '" + txtName.Text + "' "
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "'
There are two errors in your query.
If your table is Less/Stud then you must call the table name with square brackets like [Less/Stud]
Your Insert query have 4 columns but your SELECT query have only 2 columns. Thats also must be changed.
And the most important one, your query is prone to SQL injection. Try to use parameterized query.
Is "Less/Stud" your table name? I would suggest putting that in quotes, because the / seems to be confusing the database.
The WHERE clause also seems to be incomplete. A subselection is being started, but never completed.
You should also only put the fields you actually want to insert data into in the first line. Since you only provide 2 values in the SELECT clause, you can not define 4 fields to insert into.
EDIT: It turns out you want to insert values from a textbox into the Student ID and Student Name fields, based on your clarification. I have altered my suggested query to reflect this. I have not been able to test this, so I might have some mismatching quotes here and there, but I think it should be something like this:
"INSERT INTO [Less/Stud] ([LessonName],[Lesson ID],[Student ID],[StudentName])
SELECT LessonName
, LessonID
, '" + txtStuId.Text + "'
, '" + txtName.Text + "'
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "' "
You might want to consider using the String.Format() method to put the textbox values into the SQL string though. I personally think the string would be more readable that way. It would look like this:
var yourQuery = String.Format(
"INSERT INTO [Less/Stud] ([LessonName],[Lesson ID],[Student ID],[StudentName]) SELECT LessonName, LessonID, '{0}', '{1}' FROM Lessons WHERE ClassID ='{2}' "
, txtStuId.Text
, txtName.Text
, txtClassId.Text
);
Breaking up the SQL statement itself into multiple lines might also be a good idea, especially for even longer and/or more complicated statements.

Accessing two databases using Data Reader

I am trying to develop an application using ADO.NET. I have two tables in two different databases. Each of them have a portion of the complete data. Now I need to write a query such that I am able to fetch the complete record from the two tables. As an example say table 1 has Index_no,emp_ID and contact no. Table 2 has index_no, emp_name, salary and dept. The index_no is same for the same record portion in each table.
Following is the code to fetch all records where salary <20000.
sqlCmd2 = new SqlCommand("SELECT * FROM table1 WHERE Index_No =#Index_No",
TestCon);
int i = 0;
while (reader.Read()) {
ListBox1.Items.Add(reader.GetInt32(0) + " - " +
reader.GetString(1) + " - " + reader.GetString(2));
// Name.Text += reader["Name"] + "<br />"; ;
// Depart.Text += reader["Depart"] + "<br />"; ;
array1[i] = reader.GetInt32(0);
i++;
}
sqlCmd2.Parameters.Add("#Index_No", System.Data.SqlDbType.Decimal);
i = 0;
do {
sqlCmd2.Parameters["#Index_No"].Value = array1[i];
reader1 = sqlCmd2.ExecuteReader();
reader1.Read();
ListBox2.Items.Add(reader1.GetString(1));
i++;
} while (i < array1.Length);
The problem with this is that I am getting only one record info from table2 while for table 1 I get all the desired record info. The do-while loop seems to terminate after one iteration only.
It depends, what two different databases means. If the two databases run on the same SQL-Server, it is easy to access the table of the other database
SELECT * FROM OtherDb.dbo.TableOnOtherDb
If not, I would suggest you to create a database link between the two databases (see SO question How do I create and query linked database servers in SQL Server?). Then you can access the other table as above.
In both cases you can use a JOIN query to join the two tables. Then you will need only one data reader
SELECT
A.Index_no, A.emp_ID, A.contact_no,
B.emp_name, B.salary, B.dept
FROM
table1 A
INNER JOIN table2 B
ON A.Index_no = B.Index_no
WHERE
B.salary < 20000
ORDER BY
B.emp_name
UPDATE
If the number of involved records is small, then querying the second table only once by using a IN clause would be far more efficient, if you cannot link the two servers for some reason.
SELECT *
FROM table1
WHERE Index_no IN (4,12,17,30,112,167)
You would create this SQL statement like this
string[] stringArray = array1
.Select(i => i.ToString())
.ToArray();
string list = String.Join(",", stringArray);
string sql = "SELECT * FROM table1 WHERE Index_No IN (" + list + ")";
The idiomatic way of doing the second loop would be (not do while)
for (int i = 0; i < array1.Length; i++) {
...
}
Why don't you write a stored procedure which joins both the ables and gives back the results? You can connect to the second db using linked server or you can refer the second table using the dbname.tablename format.

I have inserted a row, I want to get it's ID and plus it with an int and insert in that row

I have inserted a row into my table, and I want to get it's ID and plus it with an int and inserted in that row.
But I don't know how to get it's ID.
Here is the insert code:
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin " +
" (Title, TotalID, Code ) " +
"VALUES (#Title , #TotalID, #Code )";
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin " +
" (Title, TotalID, Code ) " +
"VALUES (#Title , #TotalID, #Code ) SELECT SCOPE_IDENTITY()";
object id = objCommand.ExecuteScalar();
Try using the OUTPUT clause of SQL Server in your query - it can return any of the just inserted value (here I'm assuming your column is called ID - adapt as needed):
objCommand.Connection = objConnection;
objCommand.CommandText = "INSERT INTO Moin(Title, TotalID, Code ) " +
"OUTPUT Inserted.ID " +
"VALUES (#Title , #TotalID, #Code ); "
and then execute it like this:
int result = (int)objCommand.ExecuteScalar();
Since you're returning just one row and one column (just the INT), you can use .ExecuteScalar() to retrieve that value back from the INSERT statement.
With the OUTPUT clause, you can return any values just inserted - not just the identity column. So you could also return values that are filled by the database with default values, or whatever you need. If you return multiple values, you need to use a data reader to read them all - ExecuteScalar() only works for a single value.
But, as Anders correctly mentioned - using an ORM like Entity Framework would do all of this automatically for you and you wouldn't have to deal with those raw SQL commands anymore....
Building SQL commands in strings should be considered a legacy technique. If you use Entity Framework or linq-to-sql the retrieval of the id is handled automatically for you.
With pure SQL, use the SCOPE_IDENTITY() function to retrieve the id of the inserted element.

Categories