Solved

Help with updating an entire table with one query

Posted on 2014-12-17
9
164 Views
Last Modified: 2014-12-17
I have a table where some old code was being used to store quotes, and I have fixed the code so it stores data correctly.  But, now I need to clean up the table.  Basically, I need to search the entire table, all fields, and replace ~~ with " wherever it is found.

I can do this one at a time like Update Table Set Field = replace(Field, '~~', '"'), but I dont' want to do this 100 times with different field names.

Any ideas on how to do it at once?
0
Comment
Question by:dzirkelb
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 65

Expert Comment

by:Jim Horn
ID: 40504838
Do all of these 100+ fields have some kind of common prefix/suffix/whatever?
Are these 100+ fields the only char/varchar fields in the table?

Either way, we're talking dynamic SQL and a loop, whether it's looping through all columns that meet the above logic, or you build a table with all of these columns, and dynamic SQL uses that table.
0
 
LVL 119

Expert Comment

by:Rey Obrero
ID: 40504850
do it using recordset

dim rs as dao.recordset, j as integer
set rs=currentdb.openrecordset("tablex")
do until rs.eof
     rs .edit
       
            for j=0 to rs.fields.count-1
               rs(rs(j).name)=replace(rs(j),"~~","''")
            next
     rs.update
     
rs.movenext
loop
rs.close
0
 
LVL 119

Accepted Solution

by:
Rey Obrero earned 500 total points
ID: 40504861
or

dim db as dao.databse, rs as dao.recordset, usql as string, j as integer, strFld as string
set rs=db.openrecordset("select * from tablex")
for j=0 to rs.fields.count-1
      strfld=rs(j).name
      usql="Update tableX set [" & strfld & "]= replace([" & strfld & "],'~~','''')
      db.execute usql,dbfailonerror

next

rs.close
0
 
LVL 47

Expert Comment

by:Dale Fye (Access MVP)
ID: 40504891
is the table linked to Access from SQL Server,or is it an Access table?

In Access you could set up a loop, something like:

Dim rs as DAO.Recordset
Dim fld as DAO.Field
Dim strSQL as string

'This will open an empty recordset but will contain all of the field names and types
set RS = "SELECT * FROM yourTableName WHERE 0 = 1"

For each fld in rs.fields

    if fld.Type = 10 or fld.Type = 12 Then   'text or memo

        strSQL = "UPDATE yourTableName " _
                   & "SET [" & fld.name & "] = Replace([" & fld.name & "],'~~', '') " _
                   & "WHERE InStr([" & fld.name & "],'~~')>0
       currentdb.execute strsql, dbfailonerror

    end if

Next fld

Open in new window

This should loop through all of the fields in your table and only execute the update on those fields that are text or memo fields.

NOTE: do this with a copy of the table, not the original
0
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

 
LVL 47

Expert Comment

by:Dale Fye (Access MVP)
ID: 40504893
That's what I get for walking away for a couple of minutes.
0
 
LVL 69

Expert Comment

by:Scott Pletcher
ID: 40504908
I suggest dynamically generating the SQL statement, like this:

DECLARE @table_name varchar(257)
DECLARE @sql varchar(max)
DECLARE @sql2 varchar(max)
SET @table_name = 'dbo.<your_table_name>'

SET @sql = 'UPDATE ' + @table_name + CHAR(13) + CHAR(10) + 'SET '

SELECT @sql2 = STUFF((
    SELECT
        CAST(', [' AS varchar(max)) + CAST(c.name AS varchar(128)) + '] = ' +
            'REPLACE([' + CAST(c.name AS varchar(128)) + '], ''~~'', ''"'')'
    FROM sys.columns c
    INNER JOIN sys.types t ON
        t.system_type_id = c.system_type_id AND
        t.user_type_id = c.user_type_id
    WHERE
        c.object_id = OBJECT_ID(@table_name) AND
        --c.name NOT IN ('col1', 'col2', ...) --list of col names to exclude from UPDATE
        t.name LIKE '%char%' AND
        c.max_length >= 4
    ORDER BY c.object_id, c.column_id
    FOR XML PATH('')
), 1, 1, '')

SET @sql = @sql + @sql2

SELECT @sql
--EXEC(@sql) --uncomment when ready to run
0
 
LVL 46

Expert Comment

by:Vitor Montalvão
ID: 40504920
Try this script (replace TableNameHere with your real table name):
DECLARE @CommUPD NVARCHAR(MAX)=N'UPDATE TableNameHere SET '

SELECT @CommUPD = @CommUPD + N'' + c.name + ' = REPLACE(' + c.name + ',''~~'',''''),' + CHAR(13) + CHAR(10) 
FROM sys.objects o
	INNER JOIN sys.columns c ON c.object_id=o.object_id
WHERE o.name='TableNameHere' AND c.system_type_id IN (167, 175) -- varchar and char


SET @CommUPD = LEFT(@CommUPD, LEN(@CommUPD)-3) --Get rid of the last comma
EXEC sp_executesql @CommUPD 

Open in new window

0
 
LVL 46

Expert Comment

by:Vitor Montalvão
ID: 40504960
dim db as dao.databse, rs as dao.recordset, usql as string, j as integer, strFld as string
 set rs=db.openrecordset("select * from tablex")
 for j=0 to rs.fields.count-1
       strfld=rs(j).name
       usql="Update tableX set [" & strfld & "]= replace([" & strfld & "],'~~','''')
       db.execute usql,dbfailonerror

 next

 rs.close
This solution, apart from not being the best performance (need to select all rows to know the fields name and then will execute one update for each column) it's also not preventing error. How will deal with non text fields?
0
 
LVL 119

Expert Comment

by:Rey Obrero
ID: 40504986
<(need to select all rows to know the fields name and then will execute one update for each column)>

first of all the codes was typed in directly to the page.
to get only the field names without opening the whole rtable as recordst
change this
 set rs=db.openrecordset("select * from tablex")
with
 set rs=db.openrecordset("select * from tablex where 1=0")
0

Featured Post

Control application downtime with dependency maps

Visualize the interdependencies between application components better with Applications Manager's automated application discovery and dependency mapping feature. Resolve performance issues faster by quickly isolating problematic components.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.
Using Microsoft Access, learn some simple rules for how to construct tables in a relational database. Split up all multi-value fields into single values: Split up fields that belong to other things into separate tables: Make sure that all record…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now