Update field in table for all records using a select statement - sql

A previous developer created a table that stores the absolute path to files in our server. I want to convert them to relative paths instead.
I already wrote the portion that properly strips the string down to a relative path. My issue is understanding how to basically update each record, with a new version of its own string.
Here is what I originally tried:
UPDATE LFRX_Attachments
SET [File] = (SELECT TOP 1 SUBSTRING([File], PATINDEX('%Files\%', [File]) + 6, LEN([File]))
FROM LFRX_Attachments A
WHERE [Type] = 4 AND AttachmentId = A.AttachmentId)
However, this tanked in epic fashion by just overwriting every record to have the value of the first record in the table. Any suggestions?

UPDATE LFRX_Attachments
SET [File] = SUBSTRING([File], PATINDEX('Files\', [File]) + 6, LEN([File]))
WHERE [Type] = 4

From a readability/maintenance standpoint, you're better off selecting for the data you want to alter, then iterating through the result set and updating each record separately.

Does this work for you?
UPDATE LFRX_Attachments SET [File] = SUBSTRING([File], PATINDEX('Files\', [File]) + 6, LEN([File]))

Related

Replace or extend a URL in database table

I changed the position of some files in my file server and I need the update the URL of the file in my database.
For example from:
/sba/sbazen/test/SBA33G_TC/3300009//00150671.pdf
I want to get:
/sba/sbazen/test/SBA33G_TC/new_folder_name/3300009//00150671.pdf
Important to know: The number on SBA33G is variable. We can have SBA100G or SBA02G.
if the old folder path is always the same length you can use stuff
select len('/sba/sbazen/test/SBA33G_TC/'), stuff(t.oldval, 27, 1, '/new_folder_name/')
from (
select '/sba/sbazen/test/SBA33G_TC/3300009//00150671.pdf' oldval
) t
Why not simply use Update?
UPDATE tableName
SET
colName = '/sba/sbazen/test/SBA33G_TC/new_folder_name/3300009//00150671.pdf'
WHERE colName = '/sba/sbazen/test/SBA33G_TC/3300009//00150671.pdf'

group function is not allowed here (sql-oracle)

I want to update saboloo with the following table
update sagani
set saboloo=sum(sagani.qula + sagani.shualeduri + sagani.finaluri)
where sagnis_id='9';
Aggregation is not allowed in an update, because update changes values in the rows in the table; once the data is aggregated, the connection to the original rows is lost.
I can imagine that you mean one of two things. The first would be a simple sum within the row:
update sagani
set saboloo = (sagani.qula + sagani.shualeduri + sagani.finaluri)
where sagnis_id = 9; -- looks like a number so I assume it is a number
Alternatively, you may want to update multiple rows with the same value added up from all those rows:
update sagani s
set saboloo = (select sum(s2.qula + s2.shualeduri + s2.finaluri)
from sagani s2
where s2.sagnis_id = s.sagnis_id
)
where s.sagnis_id = 9;
Your question doesn't have enough information to infer your intention, although the use of sagnis_id suggests that there is only one row and you don't want aggregation at all.
SUM is not applicable here as your requirement is very straight forward. You can try this following script for your purpose-
UPDATE sagani
SET saboloo=(sagani.qula + sagani.shualeduri + sagani.finaluri)
WHERE sagnis_id='9';

SQL Server 403 Error When Setting a Geography Type for Update

All I need to do is simply get one geography value from a table and store it in another table. There is some logic for which row to take from the origin table so it's not just a straight select.
In any of 50 possible variants of this, I get this error when hitting the update to the target table:
Msg 403, Level 16, State 1, Line 1
Invalid operator for data type. Operator equals not equal to, type equals geography.
My SQL looks like this at the moment:
declare
#EquipmentId int
, #CurrentLocationId int
, #CurrentGeoLocation geography
, #LastUpdated datetime
select #EquipmentId =
(
select top 1 EquipmentId
from Equipment
order by EquipmentId
)
select #CurrentLocationId = (select top 1 EquipmentLocationId from EquipmentLocation where EquipmentId = #EquipmentId order by LastUpdated desc)
select #LastUpdated = (select top 1 LastUpdated from EquipmentLocation where EquipmentId = #EquipmentId order by LastUpdated desc)
UPDATE
dbo.Equipment
SET
CurrentLocationDateTime = #LastUpdated
, CurrentGeoLocation = (select GeoLocation from EquipmentLocation where EquipmentLocationId = #CurrentLocationId)
, ModifiedBy = 'system'
, ModifiedByUserId = -1
, ModifiedDate = getdate()
WHERE
EquipmentId = #EquipmentId
I have had CurrentGeoLocation set in a variable of the same type, selected into by the same statement you see in the update.
I have had an #CurrentGeoLocation variable populated by a geography::STGeomFromText as well as geography::Point() function call.
I've used Lat and Long variables to call Point and FromText functions.
All the same result, the above 403 error. I could understand it somewhat when I was concatenating various permutations of the GeomFromText function that needs well known text format for the point parameter, but field value to field value is killing me, as is the fact that I get this error no matter how I try to give the origin point data to the target table.
Thoughts?
Update:
I've been experimenting a little and found that the following works just fine:
declare #GL geography
select #GL = (select GeoLocation from EquipmentLocation where EquipmentLocationId = 25482766)
print convert(varchar, #GL.Lat)
print convert(varchar, #GL.Long)
update Equipment set CurrentGeoLocation = geography::Point(#GL.Lat, #GL.Long, 4326)-- #NewGL where EquipmentId = 10518
But then when I apply this plan to the original script, I'm back to the same error.
The data in the test is working off the exact same records as in the original script. The original script is working off a collection of EquipmentIds, on the first one, I encounter this problem. The short test script uses the same EquipmentLocationId and EquipemntId that are the selected values used to update the first Equipment record in my collection.
Solved!
The error had nothing to do with the geography type as SQL reported. By pulling items in and out of the update statement in an effort to isolate why I still get the error even if I save everything but CurrentGeoLocation and then another update for the geography, I found that CurrentLocationDateTime (datetime, null) was the culprit. Deleted the column, added it back. Problem solved. Original script works as expected.
Don't know what happened to that datetime column that caused it to throw errors against a geometry type, but it's fixed.

sqlite3 UPDATE generating nulls

I'm trying to transition from MySQL to SQLIte3 and running into an update problem. I'm using SQLite 3.6.20 on redhat.
My first line of code behaves normally
update atv_covar set noncomp= 2;
All values for noncomp (in the rightmost column) are appropriately set to 2.
select * from atv_covar;
A5202|S182|2
A5202|S183|2
A5202|S184|2
It is the second line of code that gives me problems:
update atv_covar
set noncomp= (select 1 from f4003 where
atv_covar.study = f4003.study and
atv_covar.rpid = f4003.rpid and
(rsoffrx="81" or rsoffrx="77"));
It runs without generating errors and appropriately sets atv_covar.noncomp to 1 where it matches the SELECT statement. The problem is that it changes atv_covar.noncomp for the non-matching rows to null, where I want it to keep them as 2.
select * from atv_covar;
A5202|S182|
A5202|S183|1
A5202|S184|
Any help would be welcome.
#Dan, the problem with your query is not specific to SQLite; you are updating all rows of atv_covar, but not all of them have correspondence in f4003, so these default to NULL. You should filter the update or provide a default value.
The following statement sets 1 only to the rows that macth the filtering condition:
UPDATE atv_covar
SET noncomp = 1
WHERE EXISTS (
SELECT 'x'
FROM f4003
WHERE atv_covar.study = f4003.study
AND atv_covar.rpid = f4003.rpid
AND (rsoffrx="81" or rsoffrx="77")
);
The following statement sets 1 or 2 for all rows of noncomp, depending on the filtering match (use this instead of two updates):
UPDATE atv_covar
SET noncomp = COALESCE((
SELECT 1
FROM f4003
WHERE atv_covar.study = f4003.study
AND atv_covar.rpid = f4003.rpid
AND (rsoffrx="81" or rsoffrx="77")
), 2);

sql to set an xml value

I'm a novice in mySql.
I'm trying to replace a value in the xml column of my table.
my select method works.
SELECT * FROM `comics` WHERE ExtractValue(xml,'comic/pageNumber') = 6
my replace method doesn't. I've been searching for the correct syntax for a bit now...
SET xml.modify(
replace value of ('comic/pageNumber') with 5
)
some background:
this situation comes up when i delete a comic page.
it leaves a gap in the page numbers, after which i would either:
iterate through all the comics and remove any gaps in the page numbers.
or
iterate through all comics with pageNumber larger than the deleted page, and reduce their pageNumber by 1.
How about
UPDATE comics
SET xml = UpdateXML(xml,'comic/pageNumber', '<pageNumber>5</pageNumber>')
WHERE ExtractValue(xml,'comic/pageNumber') = 6
Tested on MySQL version 5.1
UPDATE `comics`
SET xml = UpdateXML(xml,
'comic/pageNumber',
concat('<pageNumber>',(ExtractValue(xml,'comic/pageNumber')+1),'</pageNumber>'))
WHERE ExtractValue(xml,'comic/pageNumber') >= 1
You'd be better off actually storing the fields in the table, rather than a single field with xml in it. Then the following would work. Otherwise there's not much point using a relational database at all.
BEGIN;
DELETE FROM `comics`
WHERE `comicID` = :id AND `pageNumber` = :page;
UPDATE `comics` SET `pageNumber` = `pageNumber` - 1
WHERE `comicID` = :id AND `pageNumber` > :page;
COMMIT;