compare and insert only new records to sqlite database - database

I have sqlite local database. I want to insert only fresh data from remote server to local database.Since there is no time field,it is difficult to insert only new records.How can i acheive this? I require this for my hybrid mobile app. Any helps apperciated..Thanks in advance.
Two tables:
my local db table is
tbl_orders
id name age
1 yyy 30
2 xxx 20
my remote db table is
tbl_orders
id name age
1 yyy 36
2 xxx 20
3 vvv 40
4 zzz 37
In the above the remote table contains additionally two records and also the value in first record(age column) get changed.now i want to insert and update this(i.e 1st,3rd,4th) to my local sqlite table without deleting and reinserting the whole table.

You should add a UNIQUE constrain in id.
Redefining your local table:
CREATE TABLE tbl_orders(UNIQUE id, name, age);
or without redefining table
CREATE UNIQUE INDEX tbl_orders_id ON tbl_orders(id);
With constrain, your updates become a single statement:
INSERT OR REPLACE INTO local.tbl_orders SELECT * FROM remote.tbl_orders;

Your table is replicated in two DB?
If yes, you can do an INSERT with NOT EXISTS clause in WHERE condition. Alternatively, add datetime field in your source table.
Another way:
Add a boolean field in your source DB (fl_sent), populated by a trigger when create a new row in your DB or update them. Default value is false, and when you want to syncronize your DBs your select is based on this field
SELECT * FROM myTable WHERE fl_sent = 0
For a more complete answer please post your tables.
EDIT AFTER COMMENT:
Solution 1:
Add field date in your remote table (source) (if you want, you write a trigger about toggle this field) and then execute your sendable query based on this date.
Solution 2:
Add field flag (fl_sent) set by zero (if you want, you write a trigger about toggle this field) and then execute your sendable query based on this flag.

Related

How can you enter a table and column name into another table with their row contents?

I am trying to make a table that shows changes in a database with the following format:
TableName
ColumnName
OldValue
NewValue
RowID
Company
CompName
ABC
XYZ
1
Company
Address
123
456
1
Company
CompName
EDF
TRQ
2
This is all in Microsoft SQL Server, and want to try and use the system tables to connect with the data using triggers as the data is updated (using Magic Tables to capture the old/new value as it is changed).
I just don't know how to connect the table and column information with the row data to get it to display in this format.
So far I have been able to find the system tables and get them to show their updates, and the regular tables with their updates, but have not had success in figuring out how to connect them together.

Combine these 3 SQL steps into 1 query

SQL Server 2017 (In Azure) - when I need to create a new client in our clients database, I have to run three separate queries, and in between each query, do a lookup to be able to populate a part of the next query. I'd like to see if there is a way to combine all this into one query, or, parameterized stored procedure:
All of this takes place in the same database called Clients:
Step 1 - Create the client record in dbo.clients:
INSERT INTO dbo.clients
(ClientGuid, Name, Permissions)
VALUES
(NEWID(), 'Contoso', 1)
Step 2 - Get the Primary Key which was auto-created in Step 1:
SELECT ClientKey from dbo.clients
WHERE Name = 'Contoso'
Now write down the primary key (ClientKey) from that record, we'll say 12345678
Step 3 - Create a new billing code in the dbo.billingcodes table:
INSERT INTO dbo.billingcodes
(BillingCodeGuid, ClientKey, Name, ScoreId)
VALUES
(NEWID(), 12345678, 'Contoso Production Billing Code', 1)
How can I combine all this into one query or parameterized stored procedure where all I have to enter in are the two names from step 1 and 3 (assume the Permissions and ScoreId integers are always going to be 1) and also get an output at the end of the process of the created values for dbo.clients.ClientKey and dbo.billingcodes.BillingCodeGuid?
You could create a procedure that consists of both inserts with a line in between to get the ID of the inserted client. Assign the ID to a variable and pass it in to the second part.
See this post about some different ways about getting the inserted record’s ID Best way to get identity of inserted row?
You could do it by using procedure. You may find this link for creating procedure in SQL Server Link.
In case of Procedure , need to insert your data into first table. Then using IDENT_CURRENT (Ident_Current) you'll get your last inserted id from table, which will further use to insert it into next table.

In SQL Server, how to get last inserted records ID's when batch update is done?

In SQL Server, i am inserting multiple records into table using batch update. How do i get back the ID's (unique primary key) which is being created after batch update?
If I insert one record, I can get the last inserted using IDENT(tableName). I am not sure how to get if I do batch update. Please help.
For example, I have student table, with ROLE NO and NAME. ROLE NO is auto incremented by 1, as soon I insert the names into DB using java program. I will add 3 rows at a time using batch update from my java code. In DB, it gets added with ROLE NO 2, 3 and 4. How do I get these newly generated ID in my java program, please help
I tried getting ids using getgeneratedkeys method after I do executebatch. I get exception. Is batch update + get generated keys supported.?
In SQL Server when you do an insert there is an extra option your query; OUTPUT. This will let you capture back the data you inserted into the table - including your id's. You have to insert them into a temporary table; so something like this (with your table/ column names will get you there.
declare #MyNewRoles Table (Name, RoleNo)
insert into tblMyTable
(Name)
Select
Name
Output
inserted.Name, Inserted.RoleNo
into #MyNewRoles
From tblMyTableOfNames
select * from #MyNewRoles
If you don't mind adding a field to your table, you could generate a unique ID for each batch transaction (for example, a random UUID), and store that in the table as well. Then, to find the IDs associated with a given transaction you would just need something like
select my_id from my_table where batch_id = ?

Merge query using two tables in SQL server 2012

I am very new to SQL and SQL server, would appreciate any help with the following problem.
I am trying to update a share price table with new prices.
The table has three columns: share code, date, price.
The share code + date = PK
As you can imagine, if you have thousands of share codes and 10 years' data for each, the table can get very big. So I have created a separate table called a share ID table, and use a share ID instead in the first table (I was reliably informed this would speed up the query, as searching by integer is faster than string).
So, to summarise, I have two tables as follows:
Table 1 = Share_code_ID (int), Date, Price
Table 2 = Share_code_ID (int), Share_name (string)
So let's say I want to update the table/s with today's price for share ZZZ. I need to:
Look for the Share_code_ID corresponding to 'ZZZ' in table 2
If it is found, update table 1 with the new price for that date, using the Share_code_ID I just found
If the Share_code_ID is not found, update both tables
Let's ignore for now how the Share_code_ID is generated for a new code, I'll worry about that later.
I'm trying to use a merge query loosely based on the following structure, but have no idea what I am doing:
MERGE INTO [Table 1]
USING (VALUES (1,23-May-2013,1000)) AS SOURCE (Share_code_ID,Date,Price)
{ SEEMS LIKE THERE SHOULD BE AN INNER JOIN HERE OR SOMETHING }
ON Table 2 = 'ZZZ'
WHEN MATCHED THEN UPDATE SET Table 1.Price = 1000
WHEN NOT MATCHED THEN INSERT { TO BOTH TABLES }
Any help would be appreciated.
http://msdn.microsoft.com/library/bb510625(v=sql.100).aspx
You use Table1 for target table and Table2 for source table
You want to do action, when given ID is not found in Table2 - in the source table
In the documentation, that you had read already, that corresponds to the clause
WHEN NOT MATCHED BY SOURCE ... THEN <merge_matched>
and the latter corresponds to
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
Ergo, you cannot insert into source-table there.
You could use triggers for auto-insertion, when you insert something in Table1, but that will not be able to insert proper Shared_Name - trigger just won't know it.
So you have two options i guess.
1) make T-SQL code block - look for Stored Procedures. I think there also is a construct to execute anonymous code block in MS SQ, like EXECUTE BLOCK command in Firebird SQL Server, but i don't know it for sure.
2) create updatable SQL VIEW, joining Table1 and Table2 to show last most current date, so that when you insert a row in this view the view's on-insert trigger would actually insert rows to both tables. And when you would update the data in the view, the on-update trigger would modify the data.

SSIS : delete rows after an update or insert

Here is the following situation:
I have a table of StudentsA which needs to be synchronized with another table, on a different server, StudentsB. It's a one-way sync from A to B.
Since the table StudentsA can hold a large number of rows, we have a table called StudentsSync (on the input server) containing the ID of StudentsA which have been modified since the last copy from StudentsA to StudentsB.
I made the following SSIS Data Flow task:
The only problem is that I need to DELETE the row from StudentsSync after a successful copy or update. Something like this:
Any idea how this can be achieved?
It can be achieved using 3 methods
1.If your target table in OutputDB has TimeStamp columns such as Create and modified TimeStamp then rows which have got updated or inserted can be obtained by writing a simple query. You need to write the below query in the execte sql task in Control Flow to delete those rows in Sync Table .
Delete from SyncTable
where keyColumn in (Select primary_key from target
where ModifiedTimeStamp >= GETDATE() or (ModifiedTimeStamp is null
and CreateTimeStamp>=GETDATE()))
I assume StudentsA's primary key is present in Sync table along with primary key of Target table. The above condition basically checks, if a new row is added then CreateTimeStamp column will have current date and modifiedTimeStamp will be null else if the values are updated then the modifiedTimeStamp will have current date
The above query will work if you have TimeStamp columns in your target table which i feel should be there if your loading data into Data Warehouse
2.You can use MERGE syntax to perform the update and insert in Control Flow with Execute SQL Task.No need to use Data Flow Task .The below query can be used even if you don't have any TimeStamp columns
DECLARE #Output TABLE ( ActionType VARCHAR(20), SourcePrimaryKey INT)
MERGE StudentsB AS TARGET
USING StudentsA AS SOURCE
ON (TARGET.CommonColumn = SOURCE.CommonColumn)
WHEN MATCHED
THEN
UPDATE SET TARGET.column = SOURCE.Column,TARGET.ModifiedTimeStamp=GETDATE()
WHEN NOT MATCHED BY TARGET THEN
INSERT (col1,col2,Col3)
VALUES (SOURCE.col1, SOURCE.col2, SOURCE.Col3)
OUTPUT $action,
INSERTED.PrimaryKey AS SourcePrimaryKey INTO #Output
Delete from SyncTable
where PrimaryKey in (Select SourcePrimaryKey from #Output
where ActionType ='INSERT' or ActionType='UPDATE')
The code is not tested as i'm running out of time .but at-least it should give you a fair idea how to proceed . .For furthur detail on MERGE syntax read this and this
3.Use Multicast Component to duplicate the dataset for Insert and Update .Connect a MULTICAST to lookmatch output and another multicast to Lookup No match output
Add a task after "Update existing entry" and after "Insert new entry" to add the student ID to a variable which will contain the list of IDs to delete.
Enclose all of the tasks in a sequence container.
After the sequence container executes add a task to delete all the records from the sync table that are in that variable you've been populating.

Resources