Convert blank to NULL for a table - sql-server

In my table I have few columns which are having blank values. Can anyone suggest me a query by which I can replace all blanks to NULL for a given table?
EDIT
I am sorry if I couldn't specify my question correctly, I don't want to give the column name in my query. All I have is the table name. So, for a given table I want to check all columns and convert their blank values to NULL.

As an approach next stored procedure could be help:
CREATE PROCEDURE up_replaceBlanksByNulls
#schemaName nvarchar(50),
#tableName nvarchar(100)
AS
declare #query1 nvarchar(max) = ''
select #query1 = #query1 + 'UPDATE ' + #schemaName + '.' + #tableName + ' SET ' + c.COLUMN_NAME + ' = NULL WHERE ' +
c.COLUMN_NAME + ' = '''';' FROM INFORMATION_SCHEMA.COLUMNS c
WHERE C.TABLE_NAME = #tableName
EXECUTE sp_executesql #query1
GO
Usage:
up_replaceBlanksByNulls 'dbo', 'myTable'

To get rid of all blank values in a table :
CREATE PROCEDURE getRidOfBlanks
#tableName nvarchar(50)
AS
DECLARE #colName varchar(50)
DECLARE Table_Cursor CURSOR FOR
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME='#tableName'
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO #colName
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE #tableName SET #colName = NULL WHERE #colName = '';
FETCH NEXT FROM Table_Cursor INTO #colName
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;
GO
To use this, you create your procedure with my code, then you execute it with your tableName.

Simply using UPDATE like this:
UPDATE myTable SET myColumn = NULL WHERE myColumn = '';

If your column names have spaces in them, here is an alteration of #alex.b procedure.
CREATE PROCEDURE up_replaceBlanksByNulls
#schemaName nvarchar(50),
#tableName nvarchar(100)
AS
declare #query1 nvarchar(max) = ''
select #query1 = #query1 + 'UPDATE ' + #schemaName + '.' + #tableName + ' SET ' + case when c.COLUMN_NAME like '% %' then '[' + c.COLUMN_NAME + ']' Else c.COLUMN_NAME end + ' = NULL WHERE ' +
case when c.COLUMN_NAME like '% %' then '[' + c.COLUMN_NAME + ']' Else c.COLUMN_NAME end + ' = '''';' FROM INFORMATION_SCHEMA.COLUMNS c
WHERE C.TABLE_NAME = #tableName
print #query1
EXECUTE sp_executesql #query1
GO

Related

SQL Server : EXECUTE error when trying to query with variable statements

The task is to scroll through all tables and columns to find the table and column names containig the searched value. The script I use is:
IF Object_id('tempdb..#temp_sar') IS NOT NULL
DROP TABLE #temp_sar
go
CREATE TABLE #temp_table
(
[table_name] VARCHAR,
[column_name] VARCHAR
)
DECLARE #Table_Name VARCHAR
DECLARE #Column_Name VARCHAR
DECLARE #Search_Value UNIQUEIDENTIFIER = CONVERT(UNIQUEIDENTIFIER, '303D9191-E201-4299-809E-FC7B0213F73C')
DECLARE #CURSOR CURSOR
SET #CURSOR = CURSOR scroll FOR
(SELECT s.table_name,
s.column_name
FROM information_schema.columns s
WHERE s.data_type = 'uniqueidentifier')
OPEN #CURSOR
FETCH next FROM #CURSOR INTO #Table_Name, #Column_Name
WHILE ##FETCH_STATUS = 0
BEGIN
IF #Search_Value = EXEC ('select distinct' + #Column_Name + 'from'
+ #Table_Name + 'where' + #Column_Name + '='
+ #Search_Value)
INSERT INTO #temp_table ([table_name], [column_name])
VALUES (#Table_Name, #Column_Name)
FETCH next FROM #CURSOR INTO #Table_Name, #Column_Name
END
CLOSE #CURSOR
SELECT * FROM #temp_table;
When this is executed, I get an error:
Incorrect syntax near the keyword 'EXEC'
Please help me make this code work
There are a few problems with this line...
IF #Search_Value = Exec('select distinct' + #Column_Name + 'from'
+ #Table_Name + 'where' + #Column_Name + '='
+ #Search_Value)
First, make sure that you have spaces in the necessary places in your sql string...
Exec('select distinct ' + #Column_Name + ' from '
+ #Table_Name + ' where ' + #Column_Name + ' = '
+ #Search_Value
)
Next, if you execute a SELECT statement, the results are a data-set, not a scalar. This also means that the data-set is also not returned in the same as a function returns a scalar result.
It is possible to use EXEC #myReturn = spSomethingOrAnother(#param, #anotherParam); to capture anything sent back with a RETURN statement (At the end of the SP), but I don't think that works with Dynamic SQL...
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql
Your next option could be to create a table to insert the results in to, then check that table...
INSERT INTO #TABLE EXEC #query with SQL Server 2000
CREATE TABLE #result (search_value UNIQUEIDENTIFIER)
INSERT INTO
#result (
search_value
)
EXEC(
'select distinct ' + #Column_Name + ' from '
+ #Table_Name + ' where ' + #Column_Name + ' = '
+ #Search_Value
)
IF EXISTS (SELECT * FROM #result WHERE search_value = #search_value)
...
{USE PROD
GO
IF OBJECT_ID('tempdb..#source_table') IS NOT NULL DROP TABLE #source_table
GO
IF OBJECT_ID('tempdb..#result_table') IS NOT NULL DROP TABLE #result_table
GO
CREATE TABLE #result_table (Table_Name nvarchar(max),Column_Name nvarchar(max),Searched_Value uniqueidentifier)
DECLARE #CURSOR CURSOR
DECLARE #Table_Name nvarchar(max)
DECLARE #Column_Name nvarchar(max)
DECLARE #Search_Value nvarchar(max) = concat('''','ABBDFFEA-4576-4AA9-854E-A016433C54F0','''')
SET #CURSOR = CURSOR SCROLL
FOR
(
select s.TABLE_NAME, s.COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS s
where s.DATA_TYPE = 'uniqueidentifier'
)
OPEN #CURSOR
FETCH NEXT FROM #CURSOR INTO #Table_Name, #Column_Name
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #result_table (Table_Name, Column_Name, Searched_Value) EXEC('select distinct ' + ''''+ #Table_Name + '''' + ' AS Table_Name , ' + ''''+ #Column_Name + '''' + ' AS Column_Name , ' + '[' + #Column_Name + ']' + ' from ' + '[' + #Table_Name + ']' + ' where ' + '[' + #Column_Name + ']' + ' = ' + #Search_Value)
FETCH NEXT FROM #CURSOR INTO #Table_Name, #Column_Name
END
CLOSE #CURSOR
--results
SELECT * FROM #result_table}

Where clause in Stored Procedure SQL

New to stored Procedure - Can someone help me in troubleshooting the problem please? I want to achieve something as simple as :
update Table_A set Column_A = New Value where Column_A = OldValue;
but converting this to a Stored Procedure is problematic.
alter PROC test_proc
#ColumnValue as Varchar(100),
#TableValue as Varchar(50),
#NewValue as Varchar(50),
#OldValue as Varchar(50)
as
begin
Declare #Pointer VarChar(1000)
Declare Test_Cur Cursor For
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + ''''
From INFORMATION_SCHEMA.COLUMNS
Where column_name = #OldValue
and column_name = #ColumnValue
and TABLE_NAME like #TableValue
Open Test_Cur
-- Loop the cursor and execution of requests
Fetch Next From Test_Cur Into #Pointer
While (##Fetch_Status = 0)
Begin
Print #Pointer
Execute (#Pointer)
Fetch Next From Test_Cur Into #Pointer
End
-- Closing the cursor and releasing resources
Close Test_Cur
Deallocate Test_Cur
Print 'Update complete!'
end
exec dbo.test_proc #ColumnValue = 'USERCHANGED',#TableValue = 'H_%', #OldValue = '12', #NewValue = '14'
If I remove the line "Where column_name = #OldValue", the problem goes but it doesn't help me achieve my target. Suggestions please.
I think you mixed internal where with external one, try this ( I couldn't check, may be i misplaced an apex):
alter PROC test_proc
#ColumnValue as Varchar(100),
#TableValue as Varchar(50),
#NewValue as Varchar(50),
#OldValue as Varchar(50)
as
begin
Declare #Pointer VarChar(1000)
Declare Test_Cur Cursor For
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + ''' WHERE ' + + COLUMN_NAME + ' = ''' + #OldValue + ''''
From INFORMATION_SCHEMA.COLUMNS
Where column_name = #ColumnValue
and TABLE_NAME like #TableValue
Open Test_Cur
-- Loop the cursor and execution of requests
Fetch Next From Test_Cur Into #Pointer
While (##Fetch_Status = 0)
Begin
Print #Pointer
Execute (#Pointer)
Fetch Next From Test_Cur Into #Pointer
End
-- Closing the cursor and releasing resources
Close Test_Cur
Deallocate Test_Cur
Print 'Update complete!'
end
This is the logic for your cursor:
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + ''''
From INFORMATION_SCHEMA.COLUMNS
Where column_name = #OldValue and
----------^
column_name = #ColumnValue and
----------^
TABLE_NAME like #TableValue;
The first and second conditions conflict with each other. I think your intention is just:
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + ''''
From INFORMATION_SCHEMA.COLUMNS
Where column_name = #ColumnValue and
TABLE_NAME like #TableValue;
You might want to rename #ColumnValue to something like #ColumnName, which seems more apt for its use.
EDIT:
I think your intention is:
Select 'Update ' + TABLE_NAME + ' set ' + COLUMN_NAME + ' = ''' + #NewValue + ''' where ' + COLUMN_NAME + ' = ''' + #NewValue + ''''
From INFORMATION_SCHEMA.COLUMNS
Where column_name = #ColumnValue and
TABLE_NAME like #TableValue;

Programmatically set column nullable

I would like to remove not null constraint on a column, whatever its type is (nvarchar, bingint, smallint).
I am pretty sure it can be achieved using sp_executesql and building the ALTER TABLE xxx ALTER COLUMN cccc type NULL statement (by getting column type information from INFORMATION_SCHEMA.COLUMNS).
Is there any other way?
No. The only way to remove the NOT NULL constraint is by using ALTER TABLE as you describe. Any variation on how you do it will come back to the same thing. However, if you do it through a GUI tool such as SSMS it might choose to drop and re-create the table (you shouldn't lose any data but it might take much longer than you imagined). In general be careful of using GUI tools to make changes to big tables.
maybe this work :
Declare #TableName As nvarchar(250)
,#ColumnName As nvarchar(250)
,#TypeName As nvarchar(250)
Declare Cr Cursor for
Select Top 10 obj.name As TableName ,clm.name As ColumnName ,typ.name As TypeName
from sys.Columns As clm
inner join sys.Objects As obj On obj.object_Id = clm.object_id
inner join sys.types As typ On typ.system_type_id = clm.system_type_id
where obj.type = N'U'
And typ.system_type_id in (52 ,127 ,167)
open Cr
fetch next from Cr into #TableName ,#ColumnName , #TypeName
while(##fetch_status = 0)
begin
Declare #StrSQL nvarchar(max)
Set #StrSQL = N' Alter Table ' + #TableName + N' Alter Column ' + #ColumnName + N' ' + #TypeName
Print #StrSQL
fetch next from Cr into #TableName ,#ColumnName , #TypeName
End
Close CR
Deallocate CR
create procedure sp_RemoveNotNullConstraint
(
#tableName nvarchar(255),
#columnName nvarchar(255)
)
as
begin
declare #dataType nvarchar(255)
declare #sql nvarchar(max);
select #dataType =
case
when C.CHARACTER_MAXIMUM_LENGTH is not null
then C.DATA_TYPE + '(' + CAST(C.CHARACTER_MAXIMUM_LENGTH as nvarchar(255)) + ')'
else C.DATA_TYPE
end
from INFORMATION_SCHEMA.COLUMNS C
where C.TABLE_NAME = #tableName AND C.COLUMN_NAME = #columnName
set #sql = 'ALTER TABLE ' + #tableName + ' ALTER COLUMN ' + #columnName + ' ' + #dataType + ' NULL;';
exec sp_executesql #sql;
end
go

Find Replace All String Data in a SQL Server Database

I am looking for a script which finds and replaces all fields of type string within a DB with specified text.
The script would for example take the following parameters:
Search for: null
Replace with: empty-string
The primary string data types in SQL Server: Varchar, NVarchar, Text.
This script would then comb through all string based table data and look for in this case null and replace it with a empty string.
Ok I've put together the following code in the meantime.
-- Specify 'dbo' for all tables
DECLARE #schemaName VARCHAR(5) = 'dbo'
BEGIN
DECLARE #tableName VARCHAR(255) -- table name
DECLARE #tableID INT -- table id (aka syst.table.object_id)
DECLARE table_cursor CURSOR FOR
SELECT T.object_id AS TableID, T.name AS TableName FROM sys.tables T
INNER JOIN sys.schemas S ON S.schema_id = T.schema_id
WHERE S.name = #schemaName
OPEN table_cursor
FETCH NEXT FROM table_cursor INTO #tableID, #tableName
WHILE ##FETCH_STATUS = 0
BEGIN
-- construct each tables queries
DECLARE #totalColumnsFound INT = (SELECT COUNT(*) FROM sys.columns C WHERE OBJECT_ID = #tableID
-- text and nvarchar column data types chosen for me (if you need more like ntext, varcahr see sys.types for their ids)
AND (C.system_type_id = 35 OR c.system_type_id = 231))
IF (#totalColumnsFound > 0)
BEGIN
DECLARE #tableUpdateQuery VARCHAR(MAX) = 'update ' + #schemaName + '.' + #tableName + ' set ';
DECLARE #columnName VARCHAR(255) -- column name
DECLARE column_cursor CURSOR FOR
SELECT C.name AS ColumnName FROM sys.columns C WHERE OBJECT_ID = #tableID
-- text and nvarchar column data types chosen for me (if you need more like ntext, varcahr see sys.types for their ids)
AND (C.system_type_id = 35 OR c.system_type_id = 231)
OPEN column_cursor
FETCH NEXT FROM column_cursor INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
-- construct the columns for the update query, piece by piece.
-- This is also where you can apply your logic for how to handle the string update.
-- I am trimming string and updating nulls to empty strings here.
SET #tableUpdateQuery = #tableUpdateQuery + ' ' + #columnName + ' = ltrim(rtrim(isnull(' + #columnName + ',''''))),'
FETCH NEXT FROM column_cursor INTO #columnName
END
CLOSE column_cursor
DEALLOCATE column_cursor
-- trim last comma from string
SET #tableUpdateQuery = LEFT(#tableUpdateQuery, LEN(#tableUpdateQuery) - 1)
/** debuging purposes **
print 'Updating table --> ' + #tableName
print #tableUpdateQuery
print ' '
*/
-- execute dynamic sql
EXEC(#tableUpdateQuery)
END
FETCH NEXT FROM table_cursor INTO #tableID, #tableName
END
CLOSE table_cursor
DEALLOCATE table_cursor
END
--GO
this should help you:
/*
Author: sqiller
Description: Searches for a value to replace in all columns from all tables
USE: EXEC dbo.usp_Update_AllTAbles 'work', 'sqiller', 1
#search = Value to look for Replace
#newvalue = the value that will replace #search
#Test = If set to 1, it will only PRINT the UPDATE statement instead of EXEC, useful to see
what is going to update before.
*/
CREATE PROCEDURE dbo.usp_Update_AllTAbles(
#search varchar(100),
#newvalue varchar(100),
#Test bit)
AS
BEGIN
IF NOT EXISTS (select 1 from INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Tables_to_Update')
BEGIN
CREATE TABLE dbo.Tables_to_Update(
Table_name varchar(100),
Column_name varchar(100),
recordsToUpdate int
)
END
DECLARE #table varchar(100)
DECLARE #column varchar(100)
DECLARE #SQL varchar(max)
SELECT TABLE_SCHEMA+'.'+TABLE_NAME as Table_Name, 0 as Processed INTO #tables from information_schema.tables WHERE TABLE_TYPE != 'VIEW'
WHILE EXISTS (select * from #tables where processed = 0)
BEGIN
SELECT top 1 #table = table_name from #tables where processed = 0
SELECT column_name, 0 as Processed INTO #columns from information_schema.columns where TABLE_SCHEMA+'.'+TABLE_NAME = #table
WHILE EXISTS (SELECT * from #columns where processed = 0)
BEGIN
SELECT top 1 #column = COLUMN_NAME from #columns where processed = 0
SET #SQL = 'INSERT INTO Tables_to_Update
select '''+ #table +''', '''+ #column +''', count(*) from '+#table+ ' where '+ #column +' like ''%'+ #search +'%'''
EXEC(#SQL)
IF EXISTS (SELECT * FROM Tables_to_Update WHERE Table_name = #table)
BEGIN
SET #SQL = 'UPDATE '+ #table + ' SET '+ #column + ' = REPLACE('''+#column+''','''+#search+''','''+ #newvalue +''') WHERE '+ #column + ' like ''%'+#search+'%'''
--UPDATE HERE
IF (#Test = 1)
BEGIN
PRINT #SQL
END
ELSE
BEGIN
EXEC(#SQL)
END
END
UPDATE #columns SET Processed = 1 where COLUMN_NAME = #column
END
DROP TABLE #columns
UPDATE #tables SET Processed = 1 where table_name = #table
END
SELECT * FROM Tables_to_Update where recordsToUpdate > 0
END
The following will find and replace a string in every database (excluding system databases) on every table on the instance you are connected to:
Simply change 'Search String' to whatever you seek and 'Replace String' with whatever you want to replace it with.
--Getting all the databases and making a cursor
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases
DECLARE #databaseName nvarchar(1000)
--opening the cursor to move over the databases in this instance
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #databaseName
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #databaseName
--Setting up temp table for the results of our search
DECLARE #Results TABLE(TableName nvarchar(370), RealColumnName nvarchar(370), ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE #SearchStr nvarchar(100), #ReplaceStr nvarchar(100), #SearchStr2 nvarchar(110)
SET #SearchStr = 'Search String'
SET #ReplaceStr = 'Replace String'
SET #SearchStr2 = QUOTENAME('%' + #SearchStr + '%','''')
DECLARE #TableName nvarchar(256), #ColumnName nvarchar(128)
SET #TableName = ''
--Looping over all the tables in the database
WHILE #TableName IS NOT NULL
BEGIN
DECLARE #SQL nvarchar(2000)
SET #ColumnName = ''
DECLARE #result NVARCHAR(256)
SET #SQL = 'USE ' + #databaseName + '
SELECT #result = MIN(QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME))
FROM [' + #databaseName + '].INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_CATALOG = ''' + #databaseName + '''
AND QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME) > ''' + #TableName + '''
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME)
), ''IsMSShipped''
) = 0'
EXEC master..sp_executesql #SQL, N'#result nvarchar(256) out', #result out
SET #TableName = #result
PRINT #TableName
WHILE (#TableName IS NOT NULL) AND (#ColumnName IS NOT NULL)
BEGIN
DECLARE #ColumnResult NVARCHAR(256)
SET #SQL = '
SELECT #ColumnResult = MIN(QUOTENAME(COLUMN_NAME))
FROM [' + #databaseName + '].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(''[' + #databaseName + '].' + #TableName + ''', 2)
AND TABLE_NAME = PARSENAME(''[' + #databaseName + '].' + #TableName + ''', 1)
AND DATA_TYPE IN (''char'', ''varchar'', ''nchar'', ''nvarchar'')
AND TABLE_CATALOG = ''' + #databaseName + '''
AND QUOTENAME(COLUMN_NAME) > ''' + #ColumnName + ''''
PRINT #SQL
EXEC master..sp_executesql #SQL, N'#ColumnResult nvarchar(256) out', #ColumnResult out
SET #ColumnName = #ColumnResult
PRINT #ColumnName
IF #ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'USE ' + #databaseName + '
SELECT ''' + #TableName + ''',''' + #ColumnName + ''',''' + #TableName + '.' + #ColumnName + ''', LEFT(' + #ColumnName + ', 3630)
FROM ' + #TableName + ' (NOLOCK) ' +
' WHERE ' + #ColumnName + ' LIKE ' + #SearchStr2
)
END
END
END
--Declaring another temporary table
DECLARE #time_to_update TABLE(TableName nvarchar(370), RealColumnName nvarchar(370))
INSERT INTO #time_to_update
SELECT TableName, RealColumnName FROM #Results GROUP BY TableName, RealColumnName
DECLARE #MyCursor CURSOR;
BEGIN
DECLARE #t nvarchar(370)
DECLARE #c nvarchar(370)
--Looping over the search results
SET #MyCursor = CURSOR FOR
SELECT TableName, RealColumnName FROM #time_to_update GROUP BY TableName, RealColumnName
--Getting my variables from the first item
OPEN #MyCursor
FETCH NEXT FROM #MyCursor
INTO #t, #c
WHILE ##FETCH_STATUS = 0
BEGIN
-- Updating the old values with the new value
DECLARE #sqlCommand varchar(1000)
SET #sqlCommand = '
USE ' + #databaseName + '
UPDATE [' + #databaseName + '].' + #t + ' SET ' + #c + ' = REPLACE(' + #c + ', ''' + #SearchStr + ''', ''' + #ReplaceStr + ''')
WHERE ' + #c + ' LIKE ''' + #SearchStr2 + ''''
PRINT #sqlCommand
BEGIN TRY
EXEC (#sqlCommand)
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE()
END CATCH
--Getting next row values
FETCH NEXT FROM #MyCursor
INTO #t, #c
END;
CLOSE #MyCursor ;
DEALLOCATE #MyCursor;
END;
DELETE FROM #time_to_update
DELETE FROM #Results
FETCH NEXT FROM db_cursor INTO #databaseName
END
CLOSE db_cursor
DEALLOCATE db_cursor
Note: this isn't ideal, nor is it optimized
Here is another answer, similar to above (and hopefully more readable/efficient), since I recently had a similar requirement and this is how I solved it.
CREATE OR ALTER PROCEDURE UPDATE_ALL_COLUMNS
#TableNameSearchFilter NVARCHAR(100),
#TableSchema NVARCHAR(100),
#TestValue NVARCHAR(100),
#NewValue NVARCHAR(100)
AS
BEGIN
DECLARE #NRCOLUMNS INT;
DECLARE #i INT = 0;
DECLARE #COLUMN NVARCHAR(100) = '';
DECLARE #SQL NVARCHAR(MAX) = '';
DECLARE #TableToUpdate NVARCHAR(256) = '';
DECLARE #insertingNULL BIT;
IF (#NewValue IS NULL) SET #insertingNULL = 1
ELSE SET #insertingNULL = 0;
WHILE #TableToUpdate IS NOT NULL
BEGIN
SELECT #TableToUpdate = MIN(TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE #TableNameSearchFilter
AND TABLE_SCHEMA = #TableSchema
AND TABLE_NAME > #TableToUpdate;
WITH CTE1 AS
(
SELECT ROW_NUMBER() OVER (ORDER BY ORDINAL_POSITION) AS RN
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableToUpdate
AND TABLE_SCHEMA = #TableSchema
AND (#insertingNULL = 0 OR (#insertingNULL = 1 AND IS_NULLABLE = 'YES'))
)
SELECT #i = MIN(RN), #NRCOLUMNS = MAX(RN) FROM CTE1;
WHILE (#i <= #NRCOLUMNS AND #TableToUpdate IS NOT NULL)
BEGIN
WITH CTE AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY ORDINAL_POSITION) AS RN
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableToUpdate
AND TABLE_SCHEMA = #TableSchema
AND (#insertingNULL = 0 OR (#insertingNULL = 1 AND IS_NULLABLE = 'YES'))
)
SELECT #COLUMN = COLUMN_NAME
FROM CTE
WHERE RN = #i;
SET #SQL = #SQL +
N'UPDATE D SET ' + #COLUMN + N' = ' + ISNULL(N'''' + #NewValue + N'''', N'NULL')
+ N' FROM ' + #TableSchema + N'.' + #TableToUpdate + N' D WHERE CAST(D.' + #COLUMN + ' AS NVARCHAR) = ' + ISNULL(N'''' + #TestValue + N'''', N'NULL') + ';'
+ NCHAR(13) + NCHAR(10);
SET #i = #i + 1;
END;
END;
--PRINT SUBSTRING(#SQL, 1, 4000)
--PRINT SUBSTRING(#SQL, 4001, 8000)
--PRINT SUBSTRING(#SQL, 8001, 12000)
--PRINT SUBSTRING(#SQL, 12001, 16000)
--PRINT SUBSTRING(#SQL, 16001, 20000)
--PRINT SUBSTRING(#SQL, 20001, 24000)
EXEC (#SQL)
END
GO
As a usage example:
EXEC UPDATE_ALL_COLUMNS '%temp%', 'dbo', '', NULL
Parameters:
#TableNameSearchFilter - this will be used with the LIKE operator to find all the tables from your database whose names that match this value;
#TableSchema - the schema of the table (usually dbo)
#TestValue - the value to search for in ALL of the columns (and rows) of each found table;
#NewValue - the value to replace #TestValue with. Can also be NULL.
Explanation:
The EXEC statement will find ALL tables whose names contain the word 'temp', on the 'dbo' schema of your database, then search for the value '' (empty string) in ALL columns of ALL of the found tables, then replace this value with a NULL.
Obviously, if you have long(er) column/table names or the update value, make sure to update the limits on the parameters.
Make sure to first comment the last line (EXEC (#SQL)) and uncomment the lines with PRINT, just to get an idea for what the procedure does and how the final statements look like.
This is not going to work (most likely) if you want to search for the NULL value (i.e. to have #TestValue as NULL). Nevertheless, it can be easily changed to accomplish this as well, by replacing the equal sign from the WHERE clause (in the dynamic query) with IS NULL and removing the rest of the line, when #TestValue IS NULL.
Can be easily adapted to search for columns of only certain types (like VARCHAR etc).
The procedure accounts for inserting NULL values, and will only do so in NULLABLE columns.

Removing quotes added to column names from Excel import SQL Server 2008

I've noticed that when I use SSMS to import an Excel spreadsheet into SQL Server quotation marks are added. I've read somewhere that for whatever reason it's necessary for Excel to do this. Once in SQL Server, these quotes around the column names are useless and I'd like to have a programmatic way to remove them. The closest thing, which doesn't work, that I have tried to make is EXEC sp_rename 'Table.["withquotes"]', NewColumnName, 'replace(Table.["withquotes",'"','']. I'd like to loop through all of the column names in a table and use the replace function wherever a those column names contain quotation marks. Is there a typical, idiomatic way to do this?
I believe this should help...
DECLARE #tbl sysname, #col sysname
DECLARE #cmd nvarchar(max)
DECLARE cCol CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '"%"'
OPEN cCol
FETCH NEXT FROM cCol INTO #tbl, #col
WHILE ##fetch_status = 0
BEGIN
SET #cmd =
N'EXEC sp_rename ''[' + #tbl + '].[' + #col + ']'', ' +
'''' + REPLACE(#col, '"', '') + N''', ''COLUMN'''
--PRINT #cmd
EXEC sp_executeSQL #cmd
FETCH NEXT FROM cCol INTO #tbl, #col
END
CLOSE cCol
DEALLOCATE cCol
Just for the info, I had errors with the procedure of OzrenTkalcecKrznaric.
After searching, it was due to absence of schema name. So here is my version, updated to include that schema name:
DECLARE #tbl sysname, #col sysname, #sch sysname
DECLARE #cmd nvarchar(max)
DECLARE cCol CURSOR FOR
SELECT TABLE_NAME, COLUMN_NAME, TABLE_SCHEMA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '"%"'
OPEN cCol
FETCH NEXT FROM cCol INTO #tbl, #col, #sch
WHILE ##fetch_status = 0
BEGIN
SET #cmd =
N'EXEC sp_rename ''[' + #sch + '].[' + #tbl + '].[' + #col + ']'', ' +
'''' + REPLACE(#col, '"', '') + N''', ''COLUMN'''
--PRINT #cmd
EXEC sp_executeSQL #cmd
FETCH NEXT FROM cCol INTO #tbl, #col, #sch
END
CLOSE cCol
DEALLOCATE cCol
One can also generate the statements, to be then copied, pasted and executed:
USE myDb
select 'Exec sp_rename ''' + QuoteName(Schema_Name(tables.schema_id)) + '.' + QuoteName(tables.name) + '.' + QuoteName(columns.name) + '''' +
',''' + REPLACE ( columns.name , '"' , '') + ''', ''COLUMN'''
from sys.columns
join sys.tables on columns.object_id = tables.object_id
join sys.schemas on tables.schema_id = schemas.schema_id
where sys.columns.name like '"%"' AND sys.schemas.name = 'mySchema'
(replace myDb and mySchema by your values)

Resources