Replace table column value using part of same column - sql

I am updating a column in my table, replacing a column with part of its existing value:
Update Table_Name Set VarName '12345' where VarName = 'AA-BB-12345';
Update Table_Name Set VarName '99999' where VarName = 'XX-AR-99999';
...
How to do this in a loop so it makes changes through entire Table_Name table pulling out the last element of VarName and using that to update? There are 500 rows to be updated in the table, too many to do single update lines, so I need a loop to accomplish this.
I think this is close:
Update Table_Name
set VarName = ( select regexp_substr(VarName, '[^-]+,1,3 ) from Table_Name );

You aren't that far off, but your subquery isn't correlated - there is no link between the value(s) the subquery finds and the row being updated, so you're probably getting an ORA-01427 error. But you don't need the subquery since you're updating the same row:
update table_name set varname = regexp_substr(varname, '[^-]+', 1, 3);
You can do it without a regular expression too:
update table_name set varname = substr(varname, instr(varname, '-', -1) + 1);
which also has the advantage of not nulling any rows which aren't the expected pattern. Even so, you could reduce unnecessary work by only updating values with dashes:
update table_name set varname = substr(varname, instr(varname, '-', -1) + 1)
where instr(varname, '-', -1) > 0;
or
update table_name set varname = regexp_substr(varname, '[^-]+', 1, 3)
where regexp_substr(varname, '[^-]+', 1, 3) is not null;
which will only update rows where the old value has (at least) three elements.
The two updates will behave differently if there are two elements - the first one with substr/instr will always take the last part after a dash if there are any; The second one with rexexp_substr will not update one with a single dash. You've only shown one fixed pattern so none of that may be relevant to you. At least, until you run the same update again against that data...

Related

Multiple conditional updates in a single sql query PLSQL

I have some values like this in the database with three records
id
TEST_TEST1
TEST_TEST2
TEST_TEST3
Now i need to append all the values with a "PREFIX". So it becomes PREFIX_TEST_TEST1, PREFIX_TEST_TEST2 etc. But for the third value TEST_TEST3, I have to change it to PREFIX_TESTTEST3 (no underscore)
So i made it using a two update queries like below
update table set id=concat('PREFIX',id) where id in ('TEST_TEST1','TEST_TEST2');
and the second update statement
update table set id='PREFIX_TESTTEST3' where id='TEST_TEST3'
Is there any way we can make both these updates in one update statement?
CASE expression helps.
SQL> update test set
id = 'PREFIX_' || case when id = 'TEST_TEST3' then replace(id, '_')
else id
end
where id in ('TEST_TEST1','TEST_TEST2','TEST_TEST3');
3 rows updated.
SQL> select * From test;
ID
------------------------------
PREFIX_TEST_TEST1
PREFIX_TEST_TEST2
PREFIX_TESTTEST3
SQL>
You can use a case expression, for example:
update table
set id = case
when id in ('TEST_TEST1','TEST_TEST2' ) then concat('PREFIX',id)
when id ='TEST_TEST3' then 'PREFIX_TESTTEST3'
end
where id in ('TEST_TEST1','TEST_TEST2','TEST_TEST3')
You can also decode function to do that
update Your_table
set id = 'PREFIX_' || decode( id, 'TEST_TEST3', replace(id, '_', ''), id )
where id in ('TEST_TEST1', 'TEST_TEST2', 'TEST_TEST3')
;

Using IF statement in PostgreSQL to update a column that can have only 2 values

I have a table in PostgreSQL which has a column names "value" that can accept two string values (lets say "one" and "two")
I would like to create a query that updates a row and if value column is currently "one" it updates it to be "two" and vice-versa
I've tried to the the following query:
IF EXISTS(SELECT * FROM table_name WHERE filename='file1' and value='one')
THEN UPDATE table_name SET value='two' WHERE filename='file1'
ELSE
UPDATE table_name SET value='one' WHERE filename='file1'
end if;
But I keep getting "syntax error at or near "IF""
Any help please?
You wouldn't use if for this. You would use case:
update table_name
set value = (case when value = 'one' then 'two' else 'one' end);
Or, if you choose to represent the binary value as a boolean, this is simpler with not:
update table_name
set value = not value;

Comparing 2 strings and find out mismatches

I need to create a query in MariaDB 10.2. I am trying to create a query with string functions as now
Below is the scenario
One string has placeholders and another string has values of those placeholders. I want to get a tabular output in which one column have placeholders and another column have placeholder's values
value1 -->
jdbc:postgresql://$PGHOST_1$:$PGPORT_INSTANCE_1$/eventstore
value2 -->
jdbc:postgresql://1.2.3.4:5432/eventstore
now i want to get below data
Thanks in advance.
This needs a looping mechanism. Therefore, use a stored procedure or client code to do the looping:
SELECT placeholder, `value` FROM mylist;
`col` starts out looking like `value1`
foreach row in the list of replacements:
UPDATE mytable SET col =
REPLACE(col, placeholder, `value`);
Now `col` looks like your `value2`
or, if you don't want to change col:
SELECT placeholder, `value` FROM mylist;
SELECT #col := col FROM mytable;
foreach row in the list of replacements:
SET #col =
REPLACE(#col, placeholder, `value`);
then use #col in subsequent work
(value is a keyword, hence the backtics.)
From there, build the "mismatches".

how to avoid reaching max size of varchar2 in concat with update

I am new to oracle. when updating a table i am using
update my_table set column_name =concat(" ' ", column_name, "viewed by xxxx")
where item_value=2.
this value is being appended whenever some one is viewing...
Now my question is How to avoid max size of varchar(2) and set if it is just 50 characters lesser than its size. I am using this in servlet
My requirement is ..If some user views the item_value of 2, his userid is to be entered in my_table by concatinating the existing values in column_name where item_value=2, in one word I dont want to loose the earlier data in field when updating and to avoid reaching the max size of the field which is varchar2(900).
If the field reaches max size then the existing data will be ovewritten by the new data else it will be a concatination to existing data.
Just use SUBSTR:
update my_table set column_name
= SUBSTR(' '' ' || column_name || 'viewed by xxxx')
, 1, 900)
where item_value=2
P.S. concat can only take 2 arguments - I've converted your code to use the simpler || concatenation operator instead.
P.P.S. string literals in Oracle are delimited by ' not "
You should create a stored procedure that you will call to update that field. It will check what the new size will be after the update, and if it is too large then perform whatever action you need to (ie. add to archive table, trim off existing data, etc.).

Oracle Update Column LTRIM and RTRIM

I am wish to update my database data in SQL Developer using
UPDATE TABLE_NAME SET COLUMN_NAME = LTRIM(RTRIM(COLUMN_NAME))
But it does not take any effect even the msg of "rows updated" is displayed. The leading and trailing white spaces still exist behind every strings.
Any ideas?
Do you commit after update?
update tableName set col1 = trim(col1);
commit;
I had the same problem on two different tables. One the first table trim was ok, on the second no effect, the spaces were still there!
The difference was that in the first table I was using varchar2(30) and in the second table (where trim didn't work) I had char(30)
After modifying the second table from char(30) to varchar2(30) trim worked as expected.
Try this
UPDATE TABLE_NAME SET COLUMN_NAME = TRIM(COLUMN_NAME);
Trim Reference
Have you tried REGEXP_REPLACE(your column name, '\s*', '') ?
ex: UPDATE TABLE_NAME SET COLUMN_NAME = REGEXP_REPLACE(COLUMN_NAME, '\s*', '')
You get a message saying that n rows are updated because there are n rows in your table and you are applying the update to all of them.
To limit the update to only those rows where the update will have an effect, use:
UPDATE TABLE_NAME
SET COLUMN_NAME = LTRIM(RTRIM(COLUMN_NAME))
WHERE COLUMN_NAME != LTRIM(RTRIM(COLUMN_NAME));