Using Job schedule to input current date and time into columns - sql

I have 2 databases, first being Oracle and the second being SQL Server. I am able to connect the 2 databases together and data sync between the 2 databases are possible. However, I would like to know if, I can automatically insert the database's system date and time upon each entry into the table?
For example, in this case, when the data gets transferred over from Oracle, I would like the TIMEUPDATE data to mirror the real timing in SQL Server and not the data from Oracle.
I have already scripted this to create the database. All the data in my Oracle database are successfully transferfed to my SQL Server. The TimeUpdate column is created.
Sample data:
ID NAME TIMEUPDATE
---------------------------------------
1 John 2019-09-13 04:42:31.1320000
22 Mary 2019-09-09 04:42:43.6570000
3 Tommy 2019-09-17 04:42:47.0220000
4 Jill 2019-09-06 04:42:50.1170000
5 Sam 2019-09-25 04:42:51.9230000
Query:
SELECT *
INTO Customers
FROM OPENQUERY(NEWTABLE, 'SELECT ID, NAME, TIMEUPDATE FROM CUSTOMER')

Try this
SELECT *
INTO Customers
FROM OPENQUERY(NEWTABLE, 'SELECT ID, NAME, SYSDATE AS TIMEUPDATE FROM CUSTOMER')

Related

SQL: Get all rows where a logically linked columns (by their title) contains specific value

I have a SQL Server table like this:
Part-ID
ProjectA_Responsible
ProjectA_Result
ProjectB_Responsible
ProjectB_Result
101
Smith
done
Simpson
open
203
Simpson
open
Smith
open
304
Simpson
done
Smith
open
440
Smith
open
Johnson
done
The title of the column shows that there are 2 projects (ProjectA, ProjectB) and a responsible for each one. The names of the colums will always be like that, so if a ProjectC would exist, 2 additional coumns with the names "ProjectC_Responsible" and "ProjectC_Result" would get added.
I want to get all IDs where "Simpson" has to do something, so the "Result" of his project is "open".
So in my example I want to get:
Part-ID
ProjectA_Responsible
ProjectA_Result
ProjectB_Responsible
ProjectB_Result
101
Smith
done
Simpson
open
203
Simpson
open
Smith
open
I currently do not have an idea how to do this with a SQL statement. I'm using a MS Access frontend in the background so I may also solve it later with VBA, but I hope there is a direct solution with an SQL statement?
select *
from [TableName]
where (ProjectA_Responsible = 'Simpson' and ProjectA_Result = 'open')
or (ProjectB_Responsible = 'Simpson' and ProjectB_Result = 'open')
As stated in the comments, you have a problem with your table design, this design is not scalable, and requires you to change the table structure and queries every time you add a new project.
You can use another table with a correct design and transfer the existing data to it with a simple query. consider the following:
create table NewTable (Part_ID int, Project_Title nvarchar(50),Project_Responsible nvarchar(50),
Project_Result nvarchar(50));
insert into NewTable
Select Part_ID,'Project A',ProjectA_Responsible,ProjectA_Result From OldTable;
insert into NewTable
Select Part_ID,'Project B',ProjectB_Responsible,ProjectB_Result From OldTable;
Repeat the insert into NewTable Select... From OldTable according to the number of projects you have.
Now you can simply query the new table as the following:
Select Part_ID, Project_Title,Project_Responsible,Project_Result From NewTable
where Project_Responsible='Simpson' and Project_Result='open'
See a demo from here.

Writing a Trigger to find and fill the age of a patient whenever a patient record is inserted into patients table

In this question, I have to add value of age with the help of trigger.
please help me implement this question.
create or replace trigger ia_patient
after insert on patient
for each row
enable
declare
age_value number(10);
begin
DBMS_OUTPUT.PUT_LINE('Please Insert Age');
update patient set age=&age_value where ??;
end;
I am not sure what I should write after "where"
Unless it is a homework question, it really doesn't make much sense as "age" depends on current date.
Anyway, see if this helps.
SQL> create table patient
2 (id number primary key,
3 date_of_birth date,
4 age number
5 );
Table created.
Trigger: calculate age as months between sysdate and date of birth divided by 12 (as there are 12 months in a year); certainly, this is just an approximate value, but - as far as I understood - your task isn't to correctly calculate age, but to learn how to use triggers.
SQL> create or replace trigger ia_patient
2 before insert on patient
3 for each row
4 begin
5 :new.age := round(months_between(sysdate, :new.date_of_birth) / 12);
6 end;
7 /
Trigger created.
Testing:
SQL> insert into patient (id, date_of_birth) values (2, date '2000-10-05');
1 row created.
SQL> select * from patient;
ID DATE_OF_BI AGE
---------- ---------- ----------
2 2000-10-05 20
SQL>
This is written as a frame challenge to the question.
Don't use a trigger; if you do it'll insert the age now and then tomorrow, or in 6 months, or a year the person will have a birthday and your table will be incorrect. This should be something you calculate in a query at the time you want the data and could be put into a view.
CREATE TABLE people (
id INTEGER
GENERATED AS IDENTITY
CONSTRAINT people__id__pk PRIMARY KEY,
name VARCHAR2(50)
NOT NULL,
date_of_birth DATE
NOT NULL
);
Then you can create a view to calculate the ages:
CREATE VIEW people_ages ( id, name, date_of_birth, age ) AS
SELECT id,
name,
date_of_birth,
FLOOR( MONTHS_BETWEEN( SYSDATE, date_of_birth ) / 12 )
FROM people;
Which, if you have the sample data:
INSERT INTO people ( name, date_of_birth )
SELECT 'Alice', DATE '1970-01-01' FROM DUAL UNION ALL
SELECT 'Bob', DATE '2020-10-21' FROM DUAL UNION ALL
SELECT 'Carol', DATE '2000-10-21' FROM DUAL;
Then the output from the view would be:
SELECT * FROM people_ages;
ID | NAME | DATE_OF_BIRTH | AGE
-: | :---- | :------------------ | --:
1 | Alice | 1970-01-01 00:00:00 | 50
2 | Bob | 2020-10-21 00:00:00 | 0
3 | Carol | 2000-10-21 00:00:00 | 20
db<>fiddle here
Your trigger has serious defects. Despite being a totally inappropriate use of a trigger I'll go over them.
Attribute: Age. Lets just say others have sufficiently covered it. But i will return to it.
DBMS_OUTPUT: This is not output when issued. The pl/sql engine does not even output this at all. It builds an internal buffer which can later be read back and processed by the client after the pl/sql has completed. However, there is no requirement that the client do so. Typically used for debugging purposes and not available in production system.
&age_value: This is an attempt at an interactive processing. Pl/sql is not and cannot do interactive processing. This is called a substitution variable and is totally the responsibly of the client. The client sees the &... and prompts for a value. It then physically alters the statement to contain that value. For example if you reply 42 to the prompt what is sent to the compiler is age=42. The compiler actually never sees &age_value.
Update: you CAN NOT do this; it will throw the exception "ORA-04091: table ... is mutating, trigger/function may not see it". Within a trigger you cannot issue DML on the table that caused the trigger to fire. Moreover it is completely unnecessary.
where ??: Since you cannot have the update statement this is moot.
In a trigger you refer to table columns through the pesudo rows :new and/or :old. So assuming you need to stay with a trigger you rewrite as (following assumes a date_of_birth column (dob) name being inserted):
create or replace trigger ia_patient
after insert on patient
for each row
enable
begin
:new.age := trunc(months_between(sysdate, :new.dob)/12);
end;
However the problem being age is now a static value. Which will need regular updates to keep current. A much better approach just let Oracle do the calculation when needed with a view as suggested by #MT0 and abandon the trigger altogether.

How do I automatically update table columns while importing data in PostgreSQL?

I have a table my_table with layout as follows (sample rows):
id start end
1 2010-05-29 11:22:00 2010-06-06 13:45:59
2 2010-04-03 01:15:00 2010-07-21 14:30:59
3 2010-05-02 16:12:00 2010-11-01 15:12:59
Column id is of data type integer while start and end columns are in character varying(20). I have a database my_db in PostgreSQL 9.5 (x64) on Windows 7 (x64) based machine. I want to change the data type of start and end columns to timestamp without time zone. This can be achieved easily with Postgres command:
Alter table my_table alter column start type timestamp without time zone using start::timestamp without time zone
However, I would like to update the data type of these columns while importing data into my_db. I was wondering that in PostgreSQL is it possible to update column data types when data is imported (for example, when data is imported via PostGIS shapefile/DBF loader or QGIS DB Manager then PostgreSQL detects these data types automatically and changes them to the desired ones). If yes, then can someone suggest me how do I automate such process?

db2 snapshot at an instance

I have a requirement where I would like to get the snapshot od data at an instance in database.
For Eg:
At a given time - T1, EMP table in DB has following values
Col 1 Col2
1 ABC
2 DEF
3 GHI
However that data has been modified by another resource/s.
So when I checked at time T2
Col 1 Col2
1 LMN
2 PQR
3 XYZ
Is there any command available in DB2/ORACLE or any database where if, I provide Time stamp,
I can retrieve the state of Data at that timestamp??
Thanks
Both DB2 and Oracle allow you to do that by issuing queries similar to
SELECT * FROM EMP AS OF <timestamp> WHERE ...
In DB2 the table must be set up as a system temporal table (as described here, for example) before you can query it like that.
In Oracle the entire database must be enabled for flashback.
In either case the corresponding feature must be enabled before the data change to allow you to query the original state of data. You cannot make the table EMP system temporal today and query its yesterday's state; you had to enable the feature yesterday.

SQL: How to update or insert if doesn't exist?

I have a SQL insert below, which works fine, however I would like it to check if DATE=xxxx, NAME =xxxx and JOB = xxx and update HOURS if they exist otherwise insert new row. IS this possible with SQL?
"INSERT INTO TABLE (NAME, DATE, JOB, HOURS) VALUES ('BOB', '12/01/01', 'PM','30');
Trying the below OR REPLACE with the same results, a new line is added each time.
add_time = conn.prepareStatement("INSERT OR REPLACE INTO RESOURCE (NAME, DATE, JOB, HOURS) VALUES ('"+name+"', '" + date + "', '"+job+"','"+hours+"');");
For example:
if the below was in the DB, and John wanted to update his hours, it would check name, date, job were the same as the values trying to insert and if they are update HOURS only. Otherwise if none of them existed together ( John may have hours logged against another DATE or JOB) insert a new row.
Also others will also log their hours and different roles in the same DB as below.
John | 12/12/2012 | Cleaner | 20
John | 12/12/2012 | ceo | 10
Jim | 12/10/2011 | Cleaner | 5
You can use REPLACE INTO like this:
REPLACE INTO mytable (NAME, DATE, JOB, HOURS)
VALUES ('BOB', '12/01/01', 'PM','30')
But, you must create unique index for this to work:
CREATE UNIQUE INDEX myindex
ON mytable(NAME, DATE, JOB)
Note, that you should use such combination of fields for unique index that will determine if two rows are considered the same and should be replaced rather than inserted.
SQLFiddle Demo.
Note that if you comment out unique index creation, it stops working correctly.
I think this has been asked here before for sqlite:
INSERT IF NOT EXISTS ELSE UPDATE?
seems like they have a syntax for that:
INSERT OR REPLACE INTO TABLE (NAME, DATE, JOB, HOURS) VALUES ('BOB', '12/01/01', 'PM','30');