UPDATE all tables on a database - sql-server

I'm working on updating all the tables on a DB and I am having trouble getting the code correct. I was given the below code but as a previous solution but I am trying to use the SP_msforeachtable and can't get the correct format. And help with this would be wonderful. Here is the code:
USE TPP_DB
GO
DECLARE #SQL NVARCHAR(MAX)
EXEC sp_MSforeachtable
'SELECT #SQL = (
SELECT ''
UPDATE ''' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + ''.'''' + QUOTENAME(o.name) + '''
SET ''' + QUOTENAME(c.name) + '' = NULL
WHERE '' + QUOTENAME(c.name) + '' = '''''
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT #SQL
EXEC sys.sp_executesql #SQL'

You can try like this,
SELECT 'UPDATE ' + Schema_name(t.schema_id) + '.'
+ t.NAME + ' SET ' + c.NAME + ' =NULL WHERE ' + c.NAME
+ ' ='''';'
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
--WHERE c.NAME = 'ModifiedDate'
ORDER BY Schema_name(t.schema_id),
t.NAME;

Related

SQL Server Query to get Data from a Table where each row is a Table

I have a schema where I have multiple tables some with time and some without it. So I created a query where I have listed 3 tables say which has time like this :
WITH CTE AS
(
SELECT
CONCAT(schema_name(t.schema_id), '.', t.name) AS table_name,
c.name AS 'time'
FROM
sys.tables t
INNER JOIN
sys.columns c ON c.object_id = t.object_id
WHERE
schema_name(t.schema_id) = 'Prod'
AND c.name = 'mytime'
)
SELECT * FROM CTE
Now my output looks like ( I am showing 3 rows for the example):
Table O
table_name time
--------------------------
Prod.tableA mytime
Prod.tableB mytime
Prod.tableC mytime
So usually what I want is to get the max(mytime) from each Table/Schema combination . So for a single table I can do
SELECT MAX(mytime)
FROM Prod.tableA
However in this case I want to generate this from table O for each table and my output should look like:
Table F
table_name mymax(time)
--------------------------------------------
Prod.tableA max(mytime) from Prod.tableA
Prod.tableB max(mytime) from Prod.tableA
Prod.tableC max(mytime) from Prod.tableA
How to achieve this using another select/variable declaration etc? Any help or ideas will be extremely appreciated. Thanks in anticipation.
Can this help? You still have a bit of work, check if the output is what you like and then uncomment the exec.
DECLARE #SchemaName NVARCHAR(100) = 'foo',
#ColumnName NVARCHAR(100) = 'bar',
#sql NVARCHAR(max)
SELECT #SchemaName + '.'+ t.name AS [Schema.Table],'( SELECT MAX(' + #ColumnName + ') FROM ['+ #SchemaName +'].['+t.name+']) ' AS MaxValue
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #SchemaName
-------
SELECT #sql =
STUFF((
SELECT 'UNION ALL ' + 'SELECT ' + '''' + '[' + ISNULL(#SchemaName,'') + '].['+ t.name + ']' + '''' + ' AS [Schema.Table] ,( SELECT MAX(' + #ColumnName + ') FROM ['+ #SchemaName +'].['+t.name+']) AS Max' + #ColumnName + ' '
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE s.name = #SchemaName
for xml path('')
),1,10,'')
PRINT #sql
--EXEC(#sql)

Update/ replace value of extended property using T-SQL

I have around 500 columns and I want to update their extended property value using T-SQL. Basically value has | (pipe) in it and I want to replace all | with CHAR(13) + CHAR(10).
For testing I'm trying to update one value using below code and I'm getting this error
Ad hoc updates to system catalogs are not allowed.
UPDATE p
SET p.value = REPLACE(p.value, '|', CHAR(13) + CHAR(10))
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns
ON clmns.object_id = tbl.object_id
INNER JOIN sys.extended_properties AS p
ON p.major_id = tbl.object_id
AND p.minor_id = clmns.column_id
AND p.class = 1
WHERE SCHEMA_NAME(tbl.schema_id) = 'dbo'
AND tbl.name = 'ACXM_HHLD'
AND clmns.name = 'Business_Owner';
That was trickier as I thought with NVARCHAR(MAX) that cannot be converted into SQL_VARIANT and stored procedures that don't accept inline CAST expressions...
But this here should do the trick, replacing all | in all column descriptions through CrLf.
DECLARE #TSQL NVARCHAR(MAX) = 'DECLARE #Text AS NVARCHAR(4000);' + CHAR(13) + CHAR(10) + 'DECLARE #Variant AS SQL_VARIANT;' + CHAR(13) + CHAR(10);
WITH Description ([Schema], [Table], [Column], [Text]) AS (
SELECT SCHEMA_NAME(schema_id), tbl.name, clmns.name, CAST(p.value AS NVARCHAR(MAX))
FROM sys.tables AS tbl
INNER JOIN sys.all_columns AS clmns ON clmns.object_id = tbl.object_id
INNER JOIN sys.extended_properties AS p ON p.major_id = tbl.object_id AND p.minor_id = clmns.column_id AND p.Name = 'MS_Description' AND p.class = 1
)
SELECT #TSQL = #TSQL +
N'SET #Text = ''' + REPLACE(REPLACE([Text], '''', ''''''), '|', CHAR(13) + CHAR(10)) + ''';' + CHAR(13) + CHAR(10) +
N'SET #Variant = #Text;' + CHAR(13) + CHAR(10) +
N'EXEC sp_updateextendedproperty N''MS_Description'', #Variant, N''SCHEMA'', ''' + REPLACE([Schema], '''', '''''') + ''', N''TABLE'', ''' + REPLACE([Table], '''', '''''') + ''', N''COLUMN'', ''' + REPLACE([Column], '''', '''''') + '''' + CHAR(13) + CHAR(10)
FROM Description
EXEC sp_executesql #TSQL

SQL Server clone stored procedure including grants

Can I clone a stored procedure including grants to a new name?
create procedure y as clone x
Maybe you can try this SQL Server script:
Declare #sql_create NVarchar(MAX)
Declare #sql_grants NVarchar(MAX)
Declare #sp_name Varchar(MAX)
Declare #sp_new_name Varchar(MAX)
declare #object_id int
set #sp_name = '<YourSPName>'
set #sp_new_name = '<YourSPNewName>'
-- Get SP...
Select #object_id = o.object_id,
#sql_create = Replace(definition, #sp_name, #sp_new_name)
From sys.sql_modules m
inner join sys.objects o on m.object_id = o.object_id
where m.definition like '%' + #sp_name +'%'
and o.type = 'P'
-- Get all permissions
SELECT #sql_grants = COALESCE(#sql_grants + '; ', '') +
(
dp.state_desc + ' ' +
dp.permission_name collate latin1_general_cs_as +
' ON ' + '[' + s.name + ']' + '.' + '[' + Replace(o.name , #sp_name, #sp_new_name) + ']' +
' TO ' + '[' + dpr.name + ']'
)
FROM sys.database_permissions AS dp
INNER JOIN sys.objects AS o ON dp.major_id=o.object_id
INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id
INNER JOIN sys.database_principals AS dpr ON dp.grantee_principal_id=dpr.principal_id
WHERE dpr.name NOT IN ('public','guest')
and o.object_id = #object_id
-- Optional
Print (#sql_create) --Note: will cut off at TextWidth!
Print (#sql_grants)
-- Execute queries...
EXEC (#sql_create)
EXEC (#sql_grants)
I hope that helps you!

How can I replace a character in every table in SQL Server?

I want to replace a single character in each column of every table of the database; however, I don't want to do it table-by-table.
Is there a way to do the whole thing in one attempt?
Assuming only text values will be modified, you can do something like below.
IF(NOT EXISTS (SELECT * FROM sys.tables where name = 'TEMPQUERYTABLE' and type_desc = 'USER_TABLE'))
BEGIN
SELECT T.name AS Table_Name ,
C.name AS Column_Name ,
P.name AS Data_Type ,
P.max_length AS Size ,
CAST(P.precision AS VARCHAR) + '/' + CAST(P.scale AS VARCHAR) AS Precision_Scale
INTO TEMPQUERYTABLE
FROM sys.objects AS T
JOIN sys.columns AS C ON T.object_id = C.object_id
JOIN sys.types AS P ON C.system_type_id = P.system_type_id
WHERE T.type_desc = 'USER_TABLE' AND P.name in ('nvarchar','varchar') AND T.name <> 'TEMPQUERYTABLE'
END
DECLARE #SQL NVARCHAR(MAX)
DECLARE #Old_value VARCHAR(10)
DECLARE #New_value VARCHAR(10)
SET #Old_value = 'xx'
SET #New_value = 'yy'
SET #SQL = ''
SELECT #SQL = #SQL + 'UPDATE ' + Table_Name + ' SET ' + Column_Name + ' = REPLACE(' + Column_Name + ',' + #Old_value +','+ #New_value + ')' + CHAR(13) + CHAR(10)
FROM TEMPQUERYTABLE
EXEC(#SQL)
--DROP TABLE TEMPQUERYTABLE
But I'm curious to know why you need such thing done in the first place.

GET MAX(ID) FOR ALL TABLES SQL SERVER

I am trying to select Max(ID) for all tables in my database. I tried the below query but there is no AUTO-INCREMENT column available. Is there something else that I can try?
SELECT TABLE_NAME, AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb'
Are you trying to get the max value for each IDENTITY column in your DB? that is possible by modifying the script in a previous answer to examine the is_identity column on the sys.columns table.
CREATE TABLE #x(t NVARCHAR(520), c BIGINT);
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'INSERT #x SELECT '''
+ QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ''',
MAX(' + c.name + ') FROM '
+ QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ';'
FROM sys.columns C
INNER JOIN sys.tables T ON C.object_id = T.object_id
INNER JOIN sys.schemas s ON S.schema_id = T.schema_id
WHERE is_identity = 1;
EXEC sp_executesql #sql;
SELECT t, c FROM #x;
DROP TABLE #x;
CREATE TABLE #x(t NVARCHAR(520), c BIGINT);
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'INSERT #x SELECT '''
+ QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ''',
MAX(ID) FROM '
+ QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ';'
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
INNER JOIN sys.columns AS c
ON t.[object_id] = c.[object_id]
WHERE c.name = N'ID';
EXEC sp_executesql #sql;
SELECT t, c FROM #x;
DROP TABLE #x;

Resources