Get ID of inserted record then update another table - sql

Information
I am currently migrating legacy data from an old database to a new database, where the schema has changed.
Old Schema
Table Event
PK_EventID
View OldVideoConferenceParticiants
FK_EventID
FK_ParticipantID
New Schema
Table Event
PK_EventID
FK_VideoConferenceID
Table VideoConference
PK_VideoConferenceID
Table VideoConferenceParticipants
PK_VideoConferenceParticipantID
FK_VideoConferenceID
What I want to do, is:
Group all old participants based on their eventID. (done)
For each eventID, insert a new VideoConference and then set the VideoConference FK for each event to their respective newly inserted VideoConferenceID. (I can't figure this one out)
For each old participant, get the corresponding VideoConferenceID and create a new VideoConferenceParticipant. (done)
Problem
I think I might need to use MERGE but all of my attemps thus far have been disastrous. I've also tried using
INSERT ... OUPUT INSERTED.VideconferenceID
...but I can't get it right. I need to have both the EventID and the VideoConferenceID side by side somehow, which insert does not allow me to do.
Could someone please give me some guidance on how to accomplish #2 above?

Related

SQL Insert & Update Options

Ok, so I need some SQL 101 assistance. I am building a new table in SQL that will be used in a VPN connection to an outside source. I have built a view inside of SQL that contains all the information I need from the main database for this new table. I now need to push the data into the table. The problem is that the data is constantly changing and I am not really sure what my easiest way to do this is. I need to be able to copy the data from the view to the table initially but after that I need to be able to update already existing records with new information and insert new records into the table that don't already exist.
Now, the reason I am not just using the view to deal with the data needed through the VPN is because the outside source that will be using the data needs to be able to push back some values that don't exist anywhere in my table and save them to the unique records they are associated with. When I do the update, I need to leave those values that are pushed back alone and just update the values that already exist in my database.
I hope this makes sense as I need some guidance on how to do this as I have not done this before.
The table for this looks like this:
ID Name Address Email X Y Z<br>
123456 John Smith 123 Any St john#d.com 123 12 1125
X Y & Z are the fields that will be filled from an outside source which will be tied to the ID number of the record from the web service.
Thanks for the assistance

SQL Server: Remove substrings from field data by iterating through a table of city names

I have two databases, Database A and Database B.
Database A contains some data which needs to be placed in a table in Database B. However, before that can happen, some of that data must be “cleaned up” in the following way:
The table in Database A which contains the data to be placed in Database B has a field called “Desc.” Every now and then the users of the system put city names in with the data they enter into the “Desc” field. For example: a user may type in “Move furniture to new cubicle. New York. Add electric.”
Before that data can be imported into Database B the word “New York” needs to be removed from that data so that it only reads “Move furniture to new cubicle. Add electric.” However—and this is important—the original data in Database A must remain untouched. In other words, Database A’s data will still read “Move furniture to new cubicle. New York. Add electric,” while the data in Database B will read “Move furniture to new cubicle. Add electric.”
Database B contains a table which has a list of the city names which need to be removed from the “Desc” field data from Database A before being placed in Database B.
How do I construct a stored procedure or function which will grab the data from Database A, then iterate through the Cities table in Database B and if it finds a city name in the “Desc” field will remove it while keeping the rest of the information in that field thus creating a recordset which I can then use to populate the appropriate table in Database B?
I have tried several things but still haven’t cracked it. Yet I’m sure this is probably fairly easy. Any help is greatly appreciated!
Thanks.
EDIT:
The latest thing I have tried to solve this problem is this:
DECLARE #cityName VarChar(50)
While (Select COUNT(*) From ABCScanSQL.dbo.tblDiscardCitiesList) > 0
Begin
Select #cityName = ABCScanSQL.dbo.tblDiscardCitiesList.CityName FROM ABCScanSQL.dbo.tblDiscardCitiesList
SELECT JOB_NO, LTRIM(RTRIM(SUBSTRING(JOB_NO, (LEN(job_no) -2), 5))) AS LOCATION
,JOB_DESC, [Date_End] , REPLACE(Job_Desc,#cityName,' ') AS NoCity
FROM fmcs_tables.dbo.Jobt WHERE Job_No like '%loc%'
End
"Job_Desc" is the field which needs to have the city names removed.
This is a data quality issue. You can always make a copy of the [description] in Database A and call it [cleaned_desc].
One simple solution is to write a function that does the following.
1 - Read data from [tbl_remove_these_words]. These are the phrases you want removed.
2 - Compare the input - #var_description, to the rows in the table.
3 - Upon a match, replace with a empty string.
This solution depends upon a cleansing table that you maintain and update.
Run a update query that uses the input from [description] with a call to [fn_remove_these_words] and sets [cleaned_desc] to the output.
Another solution is to look at products like Melisa Data (DQ) product for SSIS or data quality services in the SQL server stack to give you a application frame work to solve the problem.

Duplicate a record and its references in web2py

In my web2py application I have a requirement to duplicate a record and all its references.
For example
one user has a product (sponserid is the user). and this product has so many features stored in other tables (reference to product id).
And my requirement is if an another user is copying this product, the a new record will generate in the product table with new productid and new sponserid. And all the reference table records will also duplicate with the new product id. Effectively a duplicate entry is creating in all the tables only change is product id and sponserid.
The product table fields will change. So I have to write a dynamic query.
If I can write a code like below
product = db(db.tbl_product.id==productid).select(db.tbl_product.ALL).first()
newproduct = db.tbl_product.insert(sponserid=newsponserid)
for field,value in product.iteritems():
if field!='sponserid':
db(db.tbl_product.id==newproduct).update(field=value)
But I cannot refer a field name like this in the update function.
Also I would like to know if there is any other better logic to achieve this requirement.
I would greatly appreciate any suggestions.
For the specific problem of using the .update() method when the field name is stored in a variable, you can do:
db(db.tbl_product.id==newproduct).update(**{field: value})
But an easier approach altogether would be something like this:
product = db(db.tbl_product.id==productid).select(db.tbl_product.ALL).first()
product.update(sponserid=newsponserid)
db.tbl_product.insert(**db.tbl_product._filter_fields(product))
The .update() method applied to the Row object updates only the Row object, not the original record in the db. The ._filter_fields() method of the table takes a record (Row, Storage, or plain dict) and returns a dict including only the fields that belong to the table (it also filters out the id field, which the db will auto-generate).

How do I efficiently create a TRIGGER which, on occasion, generates a VIEW?

On a small pre-registration database, I'm using the following SQL to generate a VIEW whenever a specific user name is given. I'm using this mainly to get a snapshot whenever a sysadmin suspects duplicate names are registering. This will be done rarely (atmost once per hour), so the database schema shouldn't be getting excessively big.
CREATE OR REPLACE TRIGGER upd_on_su_entry
AFTER UPDATE OR INSERT
ON PRE_REG_MEMBER
FOR EACH ROW
BEGIN
IF :new.MEMBER_NAME = 'SysAdmin Dup Tester' THEN
EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW mem_n AS SELECT :old.MEMBER_NAME, COUNT(:old.MEMBER_NAME) FROM MEMBER GROUP BY MEMBER_NAME';
END IF;
END;
However, this appears to be a bloated, inefficient and erroneous way of working (according to my admin). Is there a fundamental error here ? Can I take an equivalent snapshot some other way?
I'm very new to SQL, so please bear with me.
Also, I want to be using the view as :
public void dups()throws Exception
{
Calendar cal = Calendar.getInstance();
jt.setText("Duplicate List at : "+ cal.getTime());
try{
rs=stat.executeQuery("select * from upd_on_su_entry");
while(rs.next())
{
jt.append(rs.getString("MEMBER_NAME")+"\t");
jt.append(rs.getString(2)+"\t");
}
}
catch(Exception e){System.out.print("\n"+e);}
}
There seem to be some misunderstandings here.
1.) views are basically stored sql statements, not stored sql results, so your view will always display the data as it is at the point of querying the view.
2.) Never ever use DDL (create statements) and similar during normal processing of an application. Its just not the way databases are intended to work.
If you want a snapshot at a point in time, create a secondary table which contains all the columns of the original table plus a snapshot time stamp.
When ever you want to make a snapshot copy all the data you want from the original table into the snapshot table while adding the current time stamp.
Based on your comment, it sounds like you want something like this
SELECT MEMBER_NAME FROM PRE_REG_MEMBER
GROUP BY MEMBER_NAME HAVING COUNT(*) > 1;
This will return all members with more than one row in the table
Again, ask yourself "what am I trying to do"?
Don't focus on the technology. Do that after you have a clear idea of what your goal is.
If you are just trying to avoid duplicate registrations on your database, just search the users table and show an error if that username is already there.
Also, think of your datamodel carefully before going into the implementation details.

Can I insert in a programmatically defined PostgreSQL table using SQL language?

Context: I'm trying to INSERT data in a partitioned table. My table is partitioned by months, because I have lots of data (and a volume expected to increase) and the most recent data is more often queried. Any comment on the partition choice is welcome (but an answer to my question would be more than welcome).
The documentation has a partition example in which, when inserting a line, a trigger is called that checks the new data date and insert it accordingly in the right "child" table. It uses a sequence of IF and ELSIF statements, one for each month. The guy (or gal) maintaining this has to create a new table and update the trigger function every month.
I don't really like this solution. I want to code something that will work perfectly and that I won't need to update every now and then and that will outlive me and my grand-grand-children.
So I was wondering if I could make a trigger that would look like this:
INSERT INTO get_the_appropriate_table_name(NEW.date) VALUES (NEW.*);
Unfortunately all my attempts have failed. I tried using "regclass" stuffs but with no success.
In short, I want to make up a string and use it as a table name. Is that possible?
I was just about to write a trigger function using EXECUTE to insert into a table according to the date_parts of now(), or create it first if it should not exist .. when I found that somebody had already done that for us - right under the chapter of the docs you are referring to yourself:
http://www.postgresql.org/docs/9.0/interactive/ddl-partitioning.html
Scroll all the way down to user "User Comments". Laban Mwangi posted an example.
Update:
The /interactive branch of the Postgres manual has since been removed, links are redirected. So the comment I was referring to is gone. Look to these later, closely related answers for detailed instructions:
INSERT with dynamic table name in trigger function
Table name as a PostgreSQL function parameter
For partitioning, there are better solutions by now, like range partitioning in Postgres 10 or later. Example:
Better database for “keep always the 5 latest entries per ID and delete older”?