Update single column found in multiple tables - sql

I have the same column in multiple tables in my database. I need to update every table that contains that column where the value is equal to 'xxxx'. There's a very similar stack question here which is close to what I'm looking for - I just need to add another condition in my WHERE statement. I'm not sure how to include it in the query as I keep getting syntax errors.
SELECT 'UPDATE ' + TABLE_NAME + ' SET customer= ''NewCustomerValue'' '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'customer'
The part I'm having problems with is how to include the below line in the 'WHERE' statement.
AND customer='xxxx'

Try like this
SELECT 'UPDATE ' + TABLE_NAME + ' SET customer= ''NewCustomerValue'' where customer=''xxxx'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'customer'

try this:
' AND customer=''xxxx'' ' --(two ' inside a string = ')

Related

Seeking to arrange columns in a table via sql but retain all of the other columns

All,
I'm working on an AS400 and using IBM's SQL400 DB2 SQL. I have a table with 100 columns (i.e. fields) and I need to arrange the table such that several of the columns are arranged from left to right but the remaining columns can follow the arranged columns. For example-
MyDataTable
LastName1 SSN2 FirstName3 Address4 Sales5 FirstVisit6 TimeofVisit7 +93 more columns
I need to arrange the columns/fields to look as follow-
FirstName3 LastName1 SSN2 FirstVisit6 TimeofVisit7 Address4 Sales5 Remaining 93 columns
I'm not interested in GROUP BY or ORDER by as I don't want the data sorted within the column/field but I want to arrange the columns themselves . Additionally I'm trying to avoid running SELECT of 100+ columns/fields. In essence -I have a handful of columns/fields I need to place left to right in a table and I want the remaining fields to be listed in there original place. What is the most efficient way to achieve this in SQL?
I question the need for this, there's usually an opportunity to re-order the columns before presentation in the UI layer.
Unless you're just dealing with ad-hoc queries/extracts. But even there, the Run SQL Scripts component of IBM ACS will allow you to drag & drop the columns into a new order while looking at the results.
In any case, if you're ok with duplicated columns, then #smoore4's suggestion of just selecting the ones you're interested in and then all of them is the quickest solution.
SELECT t.LastName1, t.SSN2, t.FirstName3, t.Address4, t.Sales5,
t.FirstVisit6, t.TimeofVisit7, t.*
FROM MyDataTable t
Otherwise you are going to need to list the columns in the order you want. In order to save some typing, take a look at the QSYS2.SYSCOLUMNS table
select system_column_name concat ', '
from qsys2.syscolumns syscolumns
where system_table_name = 'MYTABLE'
and system_table_schema='MYLIB'
You can copy & paste the list of columns and reordered them for use in your original statement.
Lastly, note that SELECT * is generally a bad idea in any kind of production code. You may find the SQL statements I posted in this answer of some use for building lists of columns.
To avoid having to type all the columns in a large table, I use a DB2 function named listagg(). It looks like this:
select listagg(column_name, ', ') within group (order by ordinal_position)
from qsys2.syscolumns
where table_schema = 'library name'
and table_name = 'table name'
Just make sure you type your library and table names in all upper case. It will give you a comma separated string of column names. If the string is longer than 4000 characters (which can happen if your table has a lot of fields) then you can tell the function to return a larger field by casting the column larger like this:
select listagg(cast(column_name as varchar(8000)), ', ') within group (order by ordinal_position)
from qsys2.syscolumns
where table_schema = 'library name'
and table_name = 'table name'
This will produce a varchar(8000) result field. You can safely cast it all the way up to 32740, but if you do that, there can be no other columns on the row since the max row length without large objects is 32740.
Note: this is the SQL column name. To get the 10 character system name, you want to use trim(system_column_name) instead of column_name. The trim is important here as system column name is defined as char(10) vs. varchar(128), and will include trailing spaces unless they are trimmed off.
You are looking to rearrange the columns in a table?
here is an SQL function named alterTable_addColumn_likeColumn that will add a column to a table that has the same data definition as a column in a reference table. The purpose being you can use this function in a select from syscolumns SQL statement to add all the columns from the table you want to rearrange to a new table.
The alterTable_addColumn_likeColumn SQL function:
/* add a column to a table with the same data defn as the like */
/* column. */
CREATE OR REPLACE function alterTable_addColumn_likeColumn(
inSchema char(10),
inTableName char(80),
inColumnName char(80),
inLikeSchema char(10),
inLikeTable char(80),
inLIkeColumn char(80))
returns char(80)
language sql
specific core0066f
MODIFIES SQL DATA
SET OPTION datfmt = *ISO, DLYPRP = *YES, DBGVIEW = *SOURCE,
USRPRF = *OWNER, DYNUSRPRF = *OWNER
BEGIN
DECLARE VMSG CHAR(80) ;
DECLARE VCMDSTR CHAR(256) ;
declare vSqlCode decimal(5,0) default 0 ;
declare vSqlState char(5) default ' ' ;
declare vErrText char(256) default ' ' ;
declare sqlCode int default 0 ;
declare SqlState char(5) default ' ' ;
declare vDataType char(10) default ' ' ;
declare vLength decimal(5,0) default 0 ;
declare vDprc decimal(1,0) default 0 ;
declare vNullable char(1) default ' ' ;
declare vHasDefault char(1) default ' ' ;
declare vColumnDefault char(80) default ' ' ;
declare vColumnHeading char(80) default ' ' ;
declare vStmt char(2000) default ' ' ;
declare dataDefn varchar(80) default ' ' ;
declare vNotNull varchar(80) default '' ;
declare vDataDefn varchar(80) default '' ;
declare vDefault varchar(256) default '' ;
declare errmsg char(256) default ' ' ;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
begin
SET vSqlCode = SQLCODE ;
SET vSqlState = SQLstate ;
get diagnostics exception 1 vErrText = message_text ;
end ;
/* check for add column already exist. */
select a.length
into vLength
from qsys2/syscolumns a
where a.table_schema = inSchema and a.table_name = inTableName
and a.column_name = inColumnName ;
if sqlcode = 0 then
return trim(inColumnName) || ' exists' ;
end if ;
/* read data defn of like column. */
select a.data_type,
decimal(a.length,5,0) length,
decimal(coalesce(numeric_scale,0),3,0) dprc,
a.is_nullable, a.has_default,
char(a.column_default,50) column_default, a.column_heading
into vDataType, vLength, vDprc,
vNullable, vHasDefault,
vColumnDefault, vColumnHeading
from qsys2/syscolumns a
where a.table_schema = inLikeSchema and a.table_name = inLikeTable
and a.column_name = inLikeColumn ;
/* data defn of the column. */
if vDataType = 'CHAR' or vDataType = 'VARCHAR' then
set vDataDefn = trim(vDataType) || '(' || trim(char(vLength)) || ')' ;
elseif vDataType in ('DATE','TIME','TIMESTAMP') then
set vDataDefn = trim(vDataType) ;
else
set vDataDefn = trim(vDataType) || '(' || trim(char(vLength)) ||
',' || trim(char(vDprc)) || ')' ;
end if;
/* is nullable. */
if vNullable = 'N' then
set vNotNull = 'not null ' ;
else
set vNotNull = '' ;
end if ;
/* default value. */
if vHasDefault = 'Y' then
set vDefault = 'default ' || trim(vColumnDefault) ;
end if ;
set vStmt = 'alter table ' || trim(inSchema) || '/' ||
trim(inTableName) || ' ' ||
'add column ' || trim(inColumnName) || ' ' ||
vDataDefn || ' ' || vNotNull ||
' ' || vDefault ;
prepare s1 from vStmt ;
execute s1 ;
return trim(inColumnName) || ' added' ;
END
to use the function, start with a new table:
create table qgpl/steve18 (
CREATETIME timestamp default current_timestamp )
run the select * from syscolumns query. Specify the alterTable_addColumn_likeColumn function as one of the select columns. This runs the function against every row selected from the SYSCOLUMNS table. The end result is to have columns added to the definition of the target table.
select char(a.column_name,20) colname, a.data_type,
decimal(a.length,5,0) length,
decimal(coalesce(numeric_scale,0),3,0) dprc,
a.system_column_name,
altertable_addColumn_likeColumn( 'QGPL','STEVE18',
a.column_name, a.table_schema, a.table_name,
a.column_name) addcol
from qsys2/syscolumns a
where a.table_schema = 'MYLIB' and a.table_name = 'CUSMS'

Change * in SELECT to show all columns

I'm using SQL Server Management Studio.
Let's say I have a table with 100 fields, and I want to show 75 of them, how can I show all of the columns so then I can just comment out the ones I don't want? Basically de-nest the *...
Thanks!
You can open the columns "folder" under the table in the object explorer and drag the folder to your query window. It will generate the entire list of columns with commas. Not nicely formatted since it drops all the columns on a single line but it works.
You could also use sys.columns to help. This would let you copy and paste the results into your query window.
select name + ', '
from sys.columns
where object_id = object_id('YourTableName')
There are also lots and lots of third party tools that can do this kind of thing.
SSMS support GUI tool for it , but if you don't like GUI then you can use below script
declare
#table_name varchar(200) = 'Employees',
#column_sql varchar(max) = 'select ';
select
#column_sql = #column_sql + 'T.[' + COLUMN_NAME + '],'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME=#table_name;
select left(#column_sql,len(#column_sql)-1) + ' from ' + #table_name + ' T';
In NorthWind Employee Sample will get below result :
select
T.[EmployeeID],T.[LastName],T.[FirstName],T.[Title],
T.[TitleOfCourtesy],T.[BirthDate],T.[HireDate],
T.[Address],T.[City],T.[Region],T.[PostalCode],
T.[Country],T.[HomePhone],T.[Extension],T.[Photo],
T.[Notes],T.[ReportsTo],T.[PhotoPath]
from Employees T

Need an SQL script to update a new column with the values concatenated from 3 columns of the same table

I need a prepare an SQL script to be given to my production support team to run this in production. We have created a new column in the DB2 table. This column should be filled with the data by concatenating 3 column values of the same table in the same row.
To give a history, all the reason text which are entered in the front end are inserted into the request table by unstringing into 3 columns. Since they had limited length, we created a new column with increased length and going forward all insert will go into the new column. But we need to move all the existing data in the old 3 columns to his new one. S this SQL update is just an one time exercise.
Table: tab_request
We added new column to have a increased character length and to align with other table nomenclature. Now I need the script to update the column reasontext as below
update set field1 || .... should be your dml script. use coalesce() function to convert those null values to ''.
Update table1
set reasontext =
(coalesce(reason_1, '') || ' ' || coalesce(reason_2,'') || ' ' || coalesce(reason_3,''))
update tab_request set reasontext=CONCAT(reason_1,' ',reason_2,' ',reason_3)
If you want to avoid unnecessary spaces -- in the event that some reasons are NULL -- then you can use trim() with coalesce():
update table1
set reasontext = trim(coalesce(' ' || reason_1, '') ||
coalesce(' ' || reason_2, '') ||
coalesce(' ' || reason_3, '')
);
This is equivalent to concat_ws() available in some databases.

ORA-00918: Column ambiguously defined (Oracle)

I need to select a column as ' ' (empty).
Here is my query:
SELECT NAME, ' ', ' '
FROM TABLE_NAME
GROUP BY NAME
While executing at the database level query there is no problem, but at the code level I am getting Column ambiguously defined Error.
Note From suggestions, that error is because of ' '. So, I wanted to follow
SELECT NAME, ' ' AS EMPTY1, ' ' AS EMPTY2
FROM TABLE_NAME
GROUP BY NAME
How long it's correct or any alternatives, please?
Your solution is correct.
alternative:
SELECT distinct NAME,
' ' AS EMPTY1,
' ' AS EMPTY2
FROM TABLE_NAME

Is there a better way to apply isnull to all columns than what I'm doing?

A number of times over the last month I've had to replace 'null' fields with '0' to every column returned from a query.
to save a lot of time (some of these are returning a high number of columns) I've been using the following and then pasting the results for relevant columns into a new query:
select ', isnull(' + COLUMN_NAME + ', 0)' + ' as ' + COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'summary_by_scca_sales_category '
and TABLE_SCHEMA = 'property''
Essentially I'm wondering if there's a better way that I can do this? Ideally a method where I could automatically apply isnull to all columns being returned in a query (without using two queries).
For example:
I want to take a query like:
select *
from tablename
And for every column returned by * replace null results with 0 without having to write an isnull() line for each column.
edit:
Will accomplish this with a view (doh, should have thought of that). For interests / educations sake is there a way to do something like this with code also?
You could create a VIEW against the tables in question where the ISNULL logic you want is set up. Then queries against the views would return the data you want.
EDIT:
As requested, some sample code to accomplish creating the VIEWs automatically. This is pretty gross, but for something that only has to be run once it will work. Beware of type issues (you stated everything should transmute to 0 so I assume all your columns are of a suitable numeric type):
DECLARE #table_def varchar(max)
SET #table_def = 'CREATE VIEW <tname>_NoNull AS SELECT '
SELECT #table_def = REPLACE(#table_def, '<tname>', t.name) +
'ISNULL(' + c.name + ', 0) AS ' + c.name + ', '
FROM sys.tables t
INNER JOIN sys.columns c ON t.object_id = c.object_id
WHERE t.name = <<table name>>
SELECT #table_def