SQL update a value within a string from another column - sql

I have a column which contains a string within this string their is a GUID see below called voucherID, I would like to replace this GUID from another column on the same row.
<VoucherID>6c1c5c4f-3bab-4804-9a92-80b34f448cfe<VoucherID>
any help appreciated.
There are around 6000 rows.

IF on Oracle try
UPDATE YourTable T SET
T.YourXMLColumn = SUBSTR ( T.YourXMLColumn, 1, INSTR ( T.YourXMLColumn, '>' ) + 1 ) ||
T.YourValueColumn ||
SUBSTR ( T.YourXMLColumn, INSTR (T.YourXMLColumn, '<', -1 ) ) ;
Another option is just rebuilding the content with the new value
UPDATE YourTable T SET
T.YourXMLColumn = '<VoucherID>' ||
T.YourValueColumn ||
'</VoucherID>';

Why don't you select the value in the right colomn and then make an update ?
If you've a lot of switches to do you can use a loop, offcours it can be realy slow but it's the easier way, I think...

Related

Order by generated column

I have following data structure:
CREATE TABLE test(
id INTEGER PRIMARY KEY,
data TEXT NOT NULL
);
INSERT INTO test (data) VALUES ('10.20.3.40'), ('10.100.3'), ('10.20.20.40')
The problem is that i need to order by data column using integer logic (dot-separated string as array of integers).
Using order by it returns data sorted as text:
SELECT data FROM test ORDER BY data
10.100.3
10.20.20.40
10.20.3.40
Result I need to achieve:
10.20.3.40
10.20.20.40
10.100.3
The simplest method to sort it properly without reimplementing arrays in SQLite which I've found is to add zero-padding to each part of data.
So basically I need to:
Select all data from table;
Split value of data column;
Add zero-padding and join it back;
Join newly generated column with reformatted data
Order by this column
What have I already done:
WITH RECURSIVE split_str(source, part) AS (
SELECT '10.20.3.40' || '.', NULL
UNION ALL
SELECT
substr(source, instr(source, '.') + 1),
substr('000000' || source, instr(source, '.'), 6)
FROM split_str WHERE source != ''
)
SELECT group_concat(part, '.') AS new_data FROM split_str WHERE part IS NOT NULL
It splits constant string '10.20.3.40' by dot, add leading zeros to each part and join it back using group_concat(). It returns:
000010.000020.000003.000040
Now I need to apply such a modification to values of data column from test table and somehow use this values for sorting. That's result I'm trying to get:
I'm not an expert in SQL (obviously) and don't understand how to apply expression in WITH clause on each data column separately.
As you can't use GROUP_CONCAT() if you want to preserve the order, just build up another string instead.
Then, only take the records where there's no more 'unpadded' string still to be processed.
WITH RECURSIVE
test_set(original)
AS
(
SELECT '10.20.3.40'
UNION ALL
SELECT '10.100.3'
UNION ALL
SELECT '10.20.20.40'
),
split_str(original, remaining, padded)
AS
(
SELECT original, original || '.', '' FROM test_set
---------
UNION ALL
---------
SELECT
original,
substr(remaining, instr(remaining, '.') + 1),
padded || '.' || substr('000000' || remaining, instr(remaining, '.'), 6)
FROM
split_str
WHERE
remaining != ''
)
SELECT
original,
padded
FROM
split_str
WHERE
remaining = ''
ORDER BY
padded
Demo: db<>fiddle.uk
(You may or may not want to strip the leading ., depending on your needs.)

Replace Function - Handling single quotes and forward slashes in SQL SERVER 2008

I want to replace some data from my database where single quotes and slashes are present.
The line below is exactly how it appears in the database and I only want to remove 'F/D', from the record.
('P/P','F/D','DFC','DTP')
Been using varations of
UPDATE tablename SET columnname = REPLACE(columnname, '''F/D,''', '')
WHERE RECORDID = XXXXX
Also been using varations of
UPDATE tablename SET columnname = REPLACE(columnname, 'F/D,', '')
WHERE RECORDID = XXXXX
Seems like it should be a simple fix but I haven't had any luck yet - all suggestions are appreciated.
The reason your's doesn't work is because you aren't including the quotes. You are looking for F/D, and 'F/D,' and your data it is 'F/D',.
If it's simply 'F/D' from all values you want removed, then you also need to remove a comma and the quotes. This method removes 'F/D' and then, any double commas (in case 'F/D' is in the middle of the string).
declare #var varchar(64) = '(''P/P'',''F/D'',''DFC'',''DTP'')'
select replace(replace(#var,'''F/D''',''),',,',',')
--update tablename
--set columnname = replace(replace(columnname,'''F/D''',''),',,',',')
--where RECORDID = 1324
If you want to replace the second element in the string, here is a way:
select
#var
--find the location of the first comma
,charindex(',',#var,0)
--find the location of the second comma
,charindex(',',#var,charindex(',',#var) + 1)
--Put it all together, using STUFF to replace the values between this range with nothing
,stuff(#var,charindex(',',#var,0),charindex(',',#var,charindex(',',#var) + 1) - charindex(',',#var,0),'')
Your first version should work fine if the comma is in the right place:
UPDATE tablename
SET columnname = REPLACE(columnname, '''F/D'',', '')
WHERE RECORDID = XXXXX;
Note that this will not replace 'F/D' if it is the first or last element in the value. If that is an issue, I would suggest that you ask another question.

Changing LastName,FirstName to LastName,FirstInitial

I'm sure this is super easy, but how would I go about converting LastName,FirstName to LastName,FirstInitial?
For example changing Smith,John to Smith,J or Johnson,John to Johnson,J etc.
Thank You!
In case of LastName and FirstName columns:
select LastName,substr(FirstName,1,1)
from mytable
;
In case of a fullname saved in a single column:
select substr(fullname,1,instr(fullname || ',',',')-1) || substr(fullname,instr(fullname || ',',','),2)
from mytable
;
or
select regexp_replace (fullname,'([^,]*,?)(.).*','\1\2')
from mytable
;
Here is one way, using just "standard" instr and substr. Assuming your input is a single string in the format 'Smith,John':
select substr(fullname, 1, instr(fullname, ',')+1) from yourtable;
yourtable is the name of the table, and fullname is the name of the column.
instr(fullname, ',') finds the position of the comma within the input string (it would be 6 in 'Smith,John'); thensubstrtakes the substring that begins at the first position (the1in the function call) and ends at the position calculated byinstr`, PLUS 1 (to get the first initial as well).

SQL Server - Select column that contains query string and split values into anothers 'columns'

I need to do a select in a column that contains a query string like:
user_id=300&company_id=201503&status=WAITING OPERATION&count=1
I want to perform a select and break each value in a new column, something like:
user_id | company_id | status | count
300 | 201503 | WAITING OPERATION | 1
How can i do it in SQL Server without use procs?
I've tried a function:
CREATE FUNCTION [xpto].[SplitGriswold]
(
#List NVARCHAR(MAX),
#Delim1 NCHAR(1),
#Delim2 NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT
Val1 = PARSENAME(Value,2),
Val2 = PARSENAME(Value,1)
FROM
(
SELECT REPLACE(Value, #Delim2, '&') FROM
(
SELECT LTRIM(RTRIM(SUBSTRING(#List, [Number],
CHARINDEX(#Delim1, #List + #Delim1, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(#List)
AND SUBSTRING(#Delim1 + #List, [Number], LEN(#Delim1)) = #Delim1
) AS y(Value)
) AS z(Value)
);
GO
Execution:
select QueryString
from User.Log
CROSS APPLY notifier.SplitGriswold(REPLACE(QueryString, ' ', N'ŏ'), N'ŏ', '&') AS t;
But it returns me only one column with all inside:
QueryString
user_id=300&company_id=201503&status=WAITING OPERATION&count=1
Thanks in advance.
I've had to do this many times before, and you're in luck! Since you only have 3 delimiters per string, and that number is fixed, you can use SQL Server's PARSENAME function to do it. That's far less ugly than the best alternative (using the XML parsing stuff). Try this (untested) query (replace TABLE_NAME and COLUMN_NAME with the appropriate names):
SELECT
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),1) AS 'User',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),2) AS 'Company_ID',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),3) AS 'Status',
PARSENAME(REPLACE(COLUMN_NAME,'&','.'),4) AS 'Count',
FROM TABLE_NAME
That'll get you the results in the form "user_id=300", which is far and away the hard part of what you want. I'll leave it to you to do the easy part (drop the stuff before the "=" sign).
NOTE: I can't remember if PARSENAME will freak out over the illegal name character (the "=" sign). If it does, simply nest another REPLACE in there to turn it into something else, like an underscore.
You need to use SQL SUBSTRING as part of your select statement. You would first need to build the first row, then use a UNION to return the second row.

SQL Query inside a function

I am using PostgreSQL with PostGis. I am executing a query like this:
select st_geomfromtext('point(22 232)',432)
It works fine. But now I want to take a value through a query. for example:
select st_geomfromtext('point((select x from data_name where id=1) 232)' , 432)
Here data_name is some table I am using and x stores some values. Now query inside is treated as a string and no value is returned.
Please help.
ERROR: syntax error at or near "select"
Try this:
select st_geomfromtext('point(' || x || ' 232)', 432) from data_name where id=1
Postgis has a function ST_MakePoint that is faster than ST_GeomFromText.
select ST_SetSRID(ST_MakePoint(x),432) from data_name where id=1;
While #muratgu answer is generally the way to go, one minor note:
A subquery gets you a different result when no row is found for id = 1. Then you get nothing back (no row), instead of:
select st_geomfromtext(NULL, 432)
If you need a drop-in replacement:
select st_geomfromtext('point('
|| (select x from data_name where id=1)
|| ' 232)' , 432)