Oracle SQL - Update first substring - sql

I have the data in the column VPN like:
ITEM
VPN
A124343
007-46-307-RED MEDIUM
A154363
008-25-203-YELLOW MEDIUM
I have another table UPDATED_VPN as
ITEM
VPN
A124343
024
A154363
041
I want to update the first string of the VPN with the new VPN, matching the item
So
A124343 007-46-307-RED MEDIUM
will become
A124343 024-46-307-RED MEDIUM
how to do that?

You can use an UPDATE statement along with EXISTS within the WHERE condition
such as
UPDATE vpn v
SET vpn = ( SELECT u.vpn||SUBSTR(v.vpn,INSTR(v.vpn,'-'))
FROM updated_vpn u
WHERE u.item = v.item )
WHERE EXISTS ( SELECT 0 FROM updated_vpn u WHERE u.item = v.item )
Demo
Alternatively using a MERGE statement with MATCHED option might also be used such as
MERGE INTO vpn v
USING updated_vpn u
ON ( v.item = u.item )
WHEN MATCHED THEN UPDATE SET v.vpn = u.vpn||SUBSTR(v.vpn,INSTR(v.vpn,'-'))
Demo

Sample data:
create table vpns (item varchar2(10), vpn varchar2(30));
create table updated_vpns (item varchar2(10), vpn varchar2(30));
insert all
into vpns values ('A124343', '007-46-307-RED MEDIUM')
into vpns values ('A154363', '008-25-203-YELLOW MEDIUM')
into updated_vpns values ('A124343', '024')
into updated_vpns values ('A154363', '041')
select * from dual;
Update statement (could also use merge):
update vpns v
set v.vpn =
( select regexp_replace(v.vpn, '([^-]+)', u.vpn, 1, 2)
from updated_vpns u
where u.item = v.item );
Result:
ITEM VPN
---------- ------------------------------
A124343 007-024-307-RED MEDIUM
A154363 008-041-203-YELLOW MEDIUM

Related

SQL INSERT INTO WHERE NOT EXISTS with multiple conditions

I have a SQL Server database. I am looking to insert some values into multiple tables, where the data does not already exist.
Example:
Table 1
ID
Name
Material
Other
1
Aluminum
2014
v1
2
Magnesium
2013
v2
I want to develop a stored procedure such that it will insert into a table the following information:
Aluminum | 2013
My current stored procedure does not let me do this as it recognizes Magnesium | 2013 and rejects 2013 because it is being duplicated.
Also how would we compare multiple column values, for example:
INSERT WHERE NOT EXISTS (Material = 2014 AND Other = v3)
Current stored procedure:
IF EXISTS(SELECT *
FROM dbo.[01_matcard24]
WHERE NOT EXISTS (SELECT [01_matcard24].Element
FROM dbo.[01_matcard24]
WHERE dbo.[01_matcard24].Element = #new_element)
AND NOT EXISTS (SELECT [01_matcard24].Material
FROM dbo.[01_matcard24]
WHERE dbo.[01_matcard24].Material = #new_material)
)
INSERT INTO dbo.[15_matcard24_basis-UNUSED] (Element, Material)
VALUES (#new_element, #new_material)
Rather than using an IF statement, keep it set-based as part of the INSERT
Create your EXISTS sub-query to detect unique rows, not individual columns
INSERT INTO dbo.[15_matcard24_basis-UNUSED] (Element, Material)
SELECT #new_element, #new_material
WHERE NOT EXISTS (
SELECT 1
FROM dbo.[15_matcard24_basis-UNUSED]
WHERE Element = #new_element AND Material = #new_material
-- AND Other = #Other
);

how to update data from a table to store results in another

How can I copy a table to another while changing some values ?
I mean for example something like :
perso=# create table chk ( id serial primary key, Q text , R text not null unique, p text not null unique) ;
CREATE TABLE
perso=# select * from chk
perso-# ;
id | q | r | p
----+---+---+---
(0 rows)
as a destination
an I would use datas from
perso=# select * from tmp
;
idt | qt | rt | pt
-----+----+----+----
I want to copy data from tmp table to chk table and at once if possible update data on chk so
chk.p is equal to tmp.t with crypt('t', gen_salt('bf'))
I tried to copy with subselecting but I got so many different types of errors ... I just can't explain nor paste them all here.
short ask : update data from a table to store results in another
I guess the good way should be to do something like :
update chk
set
......
from tmp (colums, crypt('t', gen_salt('bf'))
....
but how ?
To copy rows from one table to another, you can use insert ... select. This is a very flexible syntax (the select part may use all the features that a regular select query can), which lets you do what you want in a simple manner:
insert into chk (id, q, r, p)
select idt, dt, rt, crypt('t', gen_salt('bf'))
from tmp
In case you wanted to update the original table:
update tmp set pt = crypt('t', gen_salt('bf')) ;

Replace t1 col with t2 col when [condition] + different datatype

I have this situation: deceduti(sigla,denominazione_provincia) , province(sigla_provincia,denominazione_provincia)
where sigla is a NUMBER and sigla_provincia is a CHAR(2).
I want to set deceduti.sigla=province.sigla_provincia where deceduti.denominazione_provincia=province.denominazione_provincia.
I have tried different ways but no one worked. I'd appreciate to understand how can i do this with join operator. There are my tries:
MERGE INTO DECEDUTI -- error with the datatypes
USING PROVINCE
ON ( DECEDUTI.DENOMINAZIONE_PROVINCIA = PROVINCE.DENOMINAZIONE_PROVINCIA )
WHEN MATCHED THEN
UPDATE SET DECEDUTI.Sigla = PROVINCE.sigla_provincia;
/
UPDATE -- oracle doesnt have the on update+policy react
(SELECT DECEDUTI.Sigla as OLD, to_number(PROVINCE.Sigla_provincia) as NEW
FROM DECEDUTI
INNER JOIN PROVINCE
ON DECEDUTI.DENOMINAZIONE_PROVINCIA = PROVINCE. DENOMINAZIONE_PROVINCIA
) t
SET t.OLD = t.NEW
/
UPDATE deceduti T
SET T.sigla =
(SELECT distinct sigla_provincia
FROM PROVINCE A
WHERE A.denominazione_provincia = T.denominazione_provincia);
This is what you have:
create table deceduti
(sigla number,
denominazione_provincia unknown_datatype
);
create table province
(sigla_provincia char(2),
denominazione_provincia unknown_datatype
);
Data stored within looks like this (according to datatypes you mentioned):
DECEDUTI:
sigla denominazione_provincia
----- -----------------------
25 1000
null 2000
PROVINCE:
sigla_provincia denominazione_provincia
--------------- -----------------------
AB 1000
X1 2000
As tables are joined on denominazione_provincia, you'd like to - for its value = 1000 - put AB into the deceduti.sigla column. How do you plan to put AB into a NUMBER datatype column? That won't work.
The simplest option is to
alter table deceduti modify sigla (char(2));
but only if sigla column is empty; shouldn't be problem to set it to NULL as it is supposed to accept a new value anyway. If you want to keep some "old" values, then it gets more complicated (creating a new column, store current sigla value in there, empty sigla, change its datatype, move data back, drop new column).
Other options are more complicated, e.g.
make sure that all sigla_provincia values are numeric so that to_number(sigla_provincia) returns a number
update deceduti.sigla values only for denominazione_provincias whose pair in province contains number in sigla_provincia

SQL or procedure to conditionally insert or update in Oracle database

I don't have much of a hands-on in SQL and procedures. I need a migration script wherein I need to update or insert a table based on data in other two tables.
Organization: id name pid 1 org1 null 2
org2 null 3
org3 1 4
org4 2
Org_Channel: org_id channel 1 CH_100 2
CH_101
Organization table has a parent-child self referenced relation. (pid null in case of parent). Org_Channel is a mapping table for parent organizations only.
Now I have a third table Org_Settings in which I need to migrate the data based on the above two tables. Each record here indicates a organization id, a setting name which is prefixed by channel name(for child org.this will be parent org.channel), and a flag. I need a migration SQL script / procedure for a setting Sign_On to be enabled as 'Y' for every organization
The current table is something like this:
Org_Settings: org_id s_name enabled 1 CH_100_Sign_On N 1 CH_100_X_O Y
4 CH_101_Sign_On Y
Now Org_Settings may or may not contain entry for each org. Also I need to migrate such that, if entry is present for Sign_On then need to update enabled = Y. Such that the result would be:
Org_Settings: org_id s_name enabled 1 CH_100_Sign_On Y 2 CH_101_Sign_On Y
3 CH_100_Sign_On Y 4 CH_101_Sign_On Y
I could think of pseudo code like:
for i in each org
var pid = getPid(i)
var id = (null == pid) ? i : pid
var channel = getChannel(id);
var sname = channel + "_Sign_On"
if(settingsEntryExists(i, sname))
updateSettingsEnable(i, sname, 'Y')
else
insertSettings(i, sname, 'Y')
Try this MERGE INTO statement. I did not understand the logic behind updating to 'Y' if entry exists and also inserting 'Y' if it does not exist. Isn't it same as simple insert?. or am I missing something? . You may tweak this query slightly if there is some missing info to clarify my question above.
SQLFiddle
MERGE
INTO Org_Settings d
USING ( select
org.id org_id,
ch.channel||
'_Sign_On' s_name ,
'Y' enabled
FROM
Organization org
JOIN Org_Channel ch ON NVL(org.pid,id) = ch.org_id
)s
ON ( d.org_id = s.org_id
AND d.s_name = s.s_name )
WHEN MATCHED THEN
UPDATE SET d.enabled = 'Y'
WHEN NOT MATCHED THEN
INSERT
(org_id,s_name,enabled
) VALUES
(s.org_id,s.s_name,s.enabled
);

SQL to update a table based on information in 2 other tables

I have 3 tables that I am currently working with. USER, WORKSTATION and USER_WORKSTATION (basically a temp table).
My
USER table consists of user_id and user_name,
WORKSTATION consists of workstation_id, workstation_name and user_id.
As of right now, the user_id column is empty for all workstations and that is my problem.
I have created a table (imported from excel) USER_WORKSTATION. It consists of only user_names and their corresponding workstation(s). Is there someway that I can write an update query that will update the WORKSTATION table with the user_id found in the USER table based on the user_name and workstation_name combination in the USER_WORKSTATION table? I do not have any constraints currently set up and I'm using Oracle.
You can use the MERGE statement for this:
MERGE
INTO WORKSTATION W1
USING (SELECT W2.rowid AS rid, U.user_id
FROM USER_WORKSTATION UW
JOIN USER U
ON UW.user_name = U.user_name
JOIN WORKSTATION W2
ON UW.workstation_name = W2.workstation_name
) q
ON (W1.rowid = q.rid)
WHEN MATCHED THEN
UPDATE
SET W1.user_id = q.user_id;
You can do an UPDATE as well, it's a little messier.
See Update statement with inner join on Oracle
Hi try this plsql block.
I Suppose one user one workstation.
Declare
user_id User.userid%type;
ws_name WorkStationUser.wsname%type;
Cursor WSUSER is select * from WorkStationUser;
user_name WorkStationUser.username%type;
Begin
Open WSUSER;
Loop
Fetch WSUSER into user_name, ws_name;
select userid into user_id from USER where username=user_name;
select wsname into ws_name from WORKSTATIONUSER where username=user_name;
update WORKSTATION set userid=user_id whrer wsname=ws_name;
EXIT WHEN WSUSER%notfound;
END LOOP;
close WSUSER;
END;