using replace in an update statement - sql

I have what Im guessing I have a stupid question but I cant seem to get my update statement to work.
I have the following query.
SELECT REPLACE(CAST(Text_col AS NVARCHAR(250)),'Vegetable oils','Refined Vegetable oils')AS 'DESCRIPTION', Text_col as 'ORIGINAL'
FROM Table1
where doc_id in (SELECT DOC_ID
FROM Table1
where Text_col like '%Vegetable oils%')
and FUNCTION_CODE = 'INGREDIENT'
This Returns me a table with two columns. It has 200+ rows. The DESCRIPTION column has the TEXT field with the updated text and the ORIGINAL has the original text so I could see all the changes side by side. I was happy with how it looked so I tried the following Query to update the tale to implement the changes.
begin transaction
UPDATE Table1
Set Text_col = REPLACE(CAST(Text_col AS NVARCHAR(MAX)),'Vegetable oils','Refined Vegetable oils')
WHERE doc_id in(SELECT DOC_ID
FROM Table1
WHERE Text_col like '%Vegetable oils%')
and function_code = 'INGREDIENT DEC
The Query runs without error but updates 0 rows. For the life of me I can't spot why it wont update the 200+ rows that appear in the above SELECT statement.
Im running this on SQL 2012 Management studio as well if that is important.
Thanks

Pretty sure your entire update could be simplified to this.
UPDATE Table1
Set Text_col = REPLACE(CAST(Text_col AS NVARCHAR(MAX)),'Vegetable oils','Refined Vegetable oils')
where FUNCTION_CODE = 'INGREDIENT'
There really is no need to limit the update since it is going to have to scan the table anyway and the subselect to pull doc_id is just adding extra work.

Related

Can you force SQL Server to send the WHERE clause to Linked Server?

I'm trying to determine if a table in my SQL Server 2012 database has any records that don't exist in a table that's on a linked Oracle 11g database.
I tried to do this with the following:
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[ORDERS]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511'
The issue is that it never completes because the ORDERS table on the linked server has about 100 million rows and as per the explain plan on SQL Server, it is trying to pull back the entire ORDERS table from the linked server and then apply the WHERE clause.
As per the explain plan, it views the remote table as having an estimated 10000 rows - I assume that's some kind of default if it is unable to get statistics..?
Even running something as simple as this:
select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511'
causes SQL Server to not send the WHERE clause and the query never completes.
I tried to use OPENQUERY however it won't let me add the doc_id to concatenate into the WHERE clause of the query string.
Then I tried to build a select FROM OPENQUERY string in a function but I can't use sp_executesql in a function to run it.
Any help is greatly appreciated.
I think this would logically work for you, but it may take too long as well.
SELECT sql_ord.*
FROM my_order_table sql_ord
LEFT JOIN LINK_ORA..[SCHEMA1].[ORDERS] ora_ord ON sql_ord.document_id = ora_ord.doc_id
WHERE sql_ord.document_id = 'N2324JKL3511'
AND ora_ord.doc_id IS NULL
Since you have problem with something as simple as select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511' have you try to create a table on the remote server that will hold the doc_id that you want to look at. So your SELECT will include a table that contain only 1 row. I'm just not sure about the INSERT since I can't test it for now. I'm assuming that everything will be done on the remote server.
So something like :
CREATE TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id (
doc_id nvarchar(12));
INSERT INTO LINK_ORA..[SCHEMA1].linked_server_doc_id (doc_id)
SELECT doc_id
FROM LINK_ORA..[SCHEMA1].[ORDERS] WHERE doc_id = 'N2324JKL3511';
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[linked_server_doc_id]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511';
DROP TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id

updating sql query value with select statement

I am trying to execute a query which is something like:
update table set column=(select column1 from table1);
I just want to store the value from other table to my column
but when i try my sql query it says
ERROR 1242 (21000): Subquery returns more than 1 row
definitely this means my table1 contains more than 1 row so i want to know that is there any way to store data into column from other table with multiple row.
or basically saving content of other table as a text something like
update table set column='Data in text from other table';
You probably need a correlation clause:
update table
set column = (select column1 from table1 where table.col = table1.col);
You need to decide what column(s) are used for the correlation.
it will work as i am getting your requirement.Please let me know if your requirement is other i ll make changes in query
update table_name t1
inner join table1 t2 on t1.id =t2.id
set column =column1
Your nested query returns multiple rows so you encountered this error.
Try in this way
UPDATE FirstTable
SET FirstTable.ColumnName =tbl2.ColumnName
FROM SecondTable tbl2 WHERE tbl2.Id = FirstTable.Id
There should be a common id or something that will help to find exact row.

SQL DISTINCT value within a field

I know how to select distinct rows, but I can't find how to extract distinct 'words/string/data' from a field to update another column.
For example, if I have data in a table like so..
Table 1
ID TEXTDATA
123 ROCK DANCE ROCK INDIE ROCK POP DISCO EURO POP
456 POP DANCE DISCO POP
I want to UPDATE another field in another table with 'distinct' data from within the TEXTDATA fields, so it would look like this
Table 2
ID NEWTEXTDATA
123 ROCK DANCE INDIE POP DISCO EURO
456 POP DANCE DISCO
I worked out how to Update one table with data from another...
UPDATE table2 JOIN table1 ON table2.ID = table1.ID SET table2.NEWTEXTDATA = table1.TEXTDATA;
But I want it to be of distinct values within the TEXTDATA records. Hope that makes some sort of sense. Is that possible to do within an update query?
Many thanks in advance
For Sql Server 2008:
You can do this by using the xml query with distinct values. The below code will give you the distinct records from given row.
cast(cast('<d>'+replace(TEXTDATA, ' ','</d><d>')+'</d>' as xml).query('distinct-values(/d)') as varchar(max))
So with the help of above function your final query will be something like below.
UPDATE
table2
SET
NEWTEXTDATA = cast(cast('<d>'+replace(TEXTDATA, ' ','</d><d>')+'</d>' as xml).query('distinct-values(/d)') as varchar(max))
FROM
table2 t2
JOIN
table1 t1
ON
t2.ID = t1.ID;
Here is the working SQLFiddle for same.
For MySql: There is no way in MySql to achieve this.
Normalize your database.
get values from table and use php explode() , and use array_unique to remove duplicate values.

Oracle SQL update

I've tried searching for this particular topic here, but haven't found the answer... Anyway, my aim is to update table (let's call it t_item), specifically column owner_id with values depending on another table (t_item_geo which is in turn linked to t_geo).
I'm not entirely sure whether the syntax below is actually valid for update statements.
UPDATE t_item SET owner_id= 6993 WHERE t_item.owner_id in
(SELECT t_item.owner_id FROM
t_item,
t_item_geo,
t_geo
WHERE
t_item.id = t_item_geo.item_id and
t_item_geo.geo_id = t_geo.id and
t_item.owner_id in (SELECT id FROM t_user WHERE network_id='fffffff') and
t_geo.id in (SELECT id FROM t_geo WHERE full_name = 'yyyyyyy')
);
Anyway, my problem with this query is that it updates far more rows than it should - if I separate just the select statement Oracle returns ~750 rows but the udpate itself updates more than 4000 rows. It's almost as if the condition was completely ignored - which would point me to perhaps incorrect syntax.
I need to update specific value in the table based on the select from few other 'joined' tables. Hope it makes sense.
Thanks for any contribution!
UPDATE: sorry - maybe it wasn't clear from the question itself, but the correct number of edited items should be ~750 and not ~4000. Thanks!
try this
MERGE INTO t_item
USING
(
SELECT t_item.owner_id FROM
t_item,
t_item_geo,
t_geo,
t_item.rowid rowid_sub
WHERE
t_item.id = t_item_geo.item_id and
t_item_geo.geo_id = t_geo.id and
t_item.owner_id in (SELECT id FROM t_user WHERE network_id='fffffff') and
t_geo.id in (SELECT id FROM t_geo WHERE full_name = 'yyyyyyy')
) on (rowid = rowid_sub)
WHEN MATCHED THEN
UPDATE SET owner_id= 6993;

Writing a single UPDATE statement that prevents duplicates

I've been trying for a few hours (probably more than I needed to) to figure out the best way to write an update sql query that will dissallow duplicates on the column I am updating.
Meaning, if TableA.ColA already has a name 'TEST1', then when I'm changing another record, then I simply can't pick a value for ColA to be 'TEST1'.
It's pretty easy to simply just separate the query into a select, and use a server layer code that would allow conditional logic:
SELECT ID, NAME FROM TABLEA WHERE NAME = 'TEST1'
IF TableA.recordcount > 0 then
UPDATE SET NAME = 'TEST1' WHERE ID = 1234
END IF
But I'm more interested to see if these two queries can be combined into a single query.
I am using Oracle to figure things out, but I'd love to see a SQL Server query as well. I figured a MERGE statement can work, but for obvious reasons you can't have the clause:
..etc.. WHEN NOT MATCHED UPDATE SET ..etc.. WHERE ID = 1234
AND you can't update a column if it's mentioned in the join (oracle limitation but not limited to SQL Server)
ALSO, I know you can put a constraint on a column that prevents duplicate values, but I'd be interested to see if there is such a query that can do this without using constraint.
Here is an example start-up attempt on my end just to see what I can come up with (explanations on it failed is not necessary):
ERROR: ORA-01732: data manipulation operation not legal on this view
UPDATE (
SELECT d.NAME, ch.NAME FROM (
SELECT 'test1' AS NAME, '2722' AS ID
FROM DUAL
) d
LEFT JOIN TABLEA a
ON UPPER(a.name) = UPPER(d.name)
)
SET a.name = 'test2'
WHERE a.name is null and a.id = d.id
I have tried merge, but just gave up thinking it's not possible. I've also considered not exists (but I'd have to be careful since I might accidentally update every other record that doesn't match a criteria)
It should be straightforward:
update personnel
set personnel_number = 'xyz'
where person_id = 1001
and not exists (select * from personnel where personnel_number = 'xyz');
If I understand correctly, you want to conditionally update a field, assuming the value is not found. The following query does this. It should work in both SQL Server and Oracle:
update table1
set name = 'Test1'
where (select count(*) from table1 where name = 'Test1') > 0 and
id = 1234