SQL Server clone stored procedure including grants - sql-server

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!

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 all tables on a database

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;

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;

How do I list (or export) the code for all triggers in a database?

I'm changing from local time to UTC-time in our database.
There are alot of triggers that copies information to history tables that currently uses GETDATE().
I would like to find every trigger that uses GETDATE() (instead of GETUTCDATE()) in the database, is there any way to do this automatic?
I've listed them by select * from sys.triggers but I also need to see the actual code to be able to find the use of GETDATE().
Your could try the following:
SELECT o.[name],
c.[text]
FROM sys.objects AS o
INNER JOIN sys.syscomments AS c
ON o.object_id = c.id
WHERE o.[type] = 'TR'
Here's the script I used to export triggers:
DECLARE #t VARCHAR (MAX)
SET #t = ''
SELECT #t = #t + 'IF EXISTS (SELECT 1 FROM sys.triggers WHERE object_id = OBJECT_ID(N''' + s.name + '.' + o.name +'''))
DROP TRIGGER ' + s.name + '.' + o.name + '
GO
' + OBJECT_DEFINITION (OBJECT_ID( s.name + '.' + o.name )) +'
GO
'
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
INNER JOIN sys.objects o2 ON o.parent_object_id = o2.object_id
WHERE o. [type] = 'TR'
AND (
OBJECTPROPERTY ( o.object_id , 'ExecIsInsertTrigger' ) = 1
OR
OBJECTPROPERTY ( o.object_id , 'ExecIsUpdateTrigger' ) = 1
OR
OBJECTPROPERTY ( o.object_id , 'ExecIsDeleteTrigger' ) = 1
)
SELECT #t AS [processing-instruction(x)] FOR XML PATH ('')
More details here if it doesn't make sense to anyone:
http://paulfentonsql.co.uk/2015/09/01/generate-createdrop-statements-for-all-triggers-of-a-given-type/
If you want to export all triggers from the database... here's some code:
DECLARE #vchServerName VARCHAR(500)
DECLARE #vchDBName VARCHAR(500)
DECLARE #intLoop INTEGER
DECLARE #intTotalRows INTEGER
DECLARE #intId INTEGER
DECLARE #vchName VARCHAR(500)
DECLARE #vchSQL VARCHAR(4000)
-- supress count (just so log looks nicer!)
SET NOCOUNT ON
-- get current DB and server
SET #vchDBName = DB_NAME()
SET #vchServerName = ##servername
-- get list of XXX
SELECT ROW_NUMBER() OVER (ORDER BY o.object_id ) fldRowNum
,o.object_id fldId
,s.name + '.' + o.name fldName
INTO #tblFound
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE [type] = 'TR'
SET #intTotalRows = ##ROWCOUNT
SET #intLoop = 1
-- loop thru list
WHILE #intLoop <= #intTotalRows
BEGIN
SELECT #intID = fldId
,#vchName = fldName
FROM #tblFound
WHERE fldRowNum = #intLoop
PRINT 'Exporting ' + #vchName + '...'
-- NOTE: I'm using a version of bcp that doens't have -D parameter so I need to use DB name here
SET #vchSQL = 'SELECT c.[text] FROM ' + #vchDBName + '.sys.syscomments AS c WHERE c.id = ' + CONVERT(VARCHAR,#intID)
SET #vchSQL = 'bcp "' + #vchSQL + '" queryout "c:\temp\' + #vchName + '.sql" -c -t -T -S ' + #vchServerName
EXEC master..XP_CMDSHELL #vchSQL
SET #intLoop = #intLoop + 1
END
DROP TABLE #tblFound
PRINT 'Done'

Tool for Scripting Table Data

Are there any free tools for scripting MSSQL table data? I'll gladly write one, but am hoping it's been done, and the app matured a bit before/
Here are some scripts I wrote for reverse engineering SQL server schemas. They may be of some use. Also, as a general interest they give some examples of how to get various bits of information out of the data dictionary. I've added an MIT license below to make permission-to-use explicit and for some basic no-implicit-warranty CYA. Enjoy.
-- ====================================================================
-- === reverse_engineer_2005.sql ======================================
-- ====================================================================
--
-- Script to generate table, index, pk, view and fk definitions from
-- a SQL Server 2005 database. Adapted from one I originally wrote
-- for SQL Server 2000. It's not comprehensive (doesn't extract
-- partition schemes) but it does do defaults and computed columns
--
-- Run the script with 'results to text' and cut/paste the output into
-- the editor window. Set the schema as described below.
--
-- Copyright (c) 2004-2008 Concerned of Tunbridge Wells
--
-- Permission is hereby granted, free of charge, to any person
-- obtaining a copy of this software and associated documentation
-- files (the "Software"), to deal in the Software without
-- restriction, including without limitation the rights to use,
-- copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the
-- Software is furnished to do so, subject to the following
-- conditions:
--
-- The above copyright notice and this permission notice shall be
-- included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-- OTHER DEALINGS IN THE SOFTWARE.
--
-- ====================================================================
--
set nocount on
-- This does a specific schema. Set the schema here
--
declare #schema varchar (max)
select #schema = 'dbo'
if object_id ('tempdb..#objects') is not null begin
drop table #objects
end
if object_id ('tempdb..#views') is not null begin
drop table #views
end
if object_id ('tempdb..#types') is not null begin
drop table #types
end
-- Gets lists of tables and views belonging to the schema
--
select o.name
,o.object_id
into #objects
from sys.objects o
join sys.schemas s
on s.schema_id = o.schema_id
where o.type in ('U')
and s.name = #schema
select o.name
,o.object_id
into #views
from sys.objects o
join sys.schemas s
on s.schema_id = o.schema_id
where o.type in ('V')
and s.name = #schema
-- Some metadata for rendering types
--
select a.*
into #types
from ((select 'decimal' as typename, 6 as format) union all
(select 'numeric', 6) union all
(select 'varbinary', 1) union all
(select 'varchar', 1) union all
(select 'char', 1) union all
(select 'nvarchar', 1) union all
(select 'nchar', 1)) a
-- This generates 'drop table' and 'drop view' statements
--
select 'if exists (select 1' + char(10) +
' from sys.objects o' + char(10) +
' join sys.schemas s' + char(10) +
' on o.schema_id = s.schema_id' + char(10) +
' where o.name = ''' + o.name + '''' + char(10) +
' and s.name = ''' + #schema +'''' + char(10) +
' and o.type = ''U'') begin' + char(10) +
' drop table [' + #schema + '].[' + o.name + ']' + char(10) +
'end' + char(10) +
'go' + char(10)
from sys.objects o
join #objects o2
on o.object_id = o2.object_id
where o.type = 'U'
select 'if exists (select 1' + char(10) +
' from sys.objects o' + char(10) +
' join sys.schemas s' + char(10) +
' on o.schema_id = s.schema_id' + char(10) +
' where o.name = ''' + o.name + '''' + char(10) +
' and s.name = ''' + #schema + '''' + char(10) +
' and o.type = ''V'') begin' + char(10) +
' drop view [' + #schema + '].[' + o.name + ']' + char(10) +
'end' + char(10) +
'go' + char(10)
from sys.objects o
join #objects o2
on o.object_id = o2.object_id
where o.type = 'V'
-- This generates table definitions
--
select case when c.column_id =
(select min(c2.column_id)
from sys.columns c2
where c2.object_id = o.object_id)
then 'create table [' + #schema + '].[' + isnull(o.name, 'XYZZY') + '] (' + char(10)
else ''
end +
left(' [' +rtrim(c.name) + '] ' +
' ', 48) +
isnull(calc.text,
t.name +
case when tc.format & 2 = 2
then ' (' +convert (varchar, c.precision) +
case when tc.format & 2 = 2
then ', ' + convert (varchar, c.scale)
else ''
end + ')'
when tc.format & 1 = 1
then ' (' + convert (varchar, c.max_length) + ')'
else ''
end + ' ' +
case when c.is_nullable <> 0 then 'null'
else 'not null'
end + isnull(ident.text, isnull(con.text, ''))) +
case when c.column_id =
(select max(c2.column_id)
from sys.columns c2
where c2.object_id = o.object_id)
then char(10) + ')' + char(10) + 'go' + char(10)
else ','
end
from sys.objects o
join #objects o2
on o.object_id = o2.object_id
join sys.columns c
on c.object_id = o.object_id
join sys.types t
on c.user_type_id = t.user_type_id
left join
(select object_id,
column_id,
'as ' + definition as text
from sys.computed_columns) calc
on calc.object_id = o.object_id
and calc.column_id = c.column_id
left join
(select parent_object_id,
parent_column_id,
' default ' + definition as text
from sys.default_constraints) con
on con.parent_object_id = o.object_id
and con.parent_column_id = c.column_id
left join
(select o.object_id,
col.column_id,
' identity (' + convert(varchar, ident_seed(o.name)) + ', ' +
convert(varchar, ident_incr(o.name)) + ')' as text
from sys.objects o
join sys.columns col
on o.object_id = col.object_id
where columnproperty (o.object_id, col.name, 'IsIdentity') = 1) as ident
on ident.object_id = o.object_id
and ident.column_id = c.column_id
left join #types tc
on tc.typename = t.name
where o.type = 'U'
order by o.name,
c.column_id
-- This generates view definitions
--
select definition + char(10) + 'go' + char(10)
from sys.sql_modules c
join sys.objects o
on c.object_id = o.object_id
join #views o2
on o.object_id = o2.object_id
-- This generates PK and unique constraints
--
select case when ik.key_ordinal =
(select min(ik2.key_ordinal)
from sys.index_columns ik2
where ik2.object_id = ik.object_id
and ik2.index_id = ik.index_id)
then 'alter table [' + rtrim (s.name) + '].[' + rtrim(t.name) + ']' + char(10) +
' add constraint [' + rtrim (pk.name) + '] ' +
case when pk.type = 'PK' then 'primary key'
when pk.type = 'UQ' then 'unique'
else 'foobar'
end + char(10) +
' ('
else ' ,'
end +
'[' + rtrim(c.name) + ']' +
case when ik.key_ordinal =
(select max(ik2.key_ordinal)
from sys.index_columns ik2
where ik2.object_id = ik.object_id
and ik2.index_id = ik.index_id)
then ')' + char(10) + 'go' + char(10)
else ''
end
from sys.objects t -- table
join #objects o
on t.object_id = o.object_id
join sys.schemas s
on s.schema_id = t.schema_id
join sys.objects pk -- key
on pk.parent_object_id = t.object_id
join sys.columns c -- columns
on c.object_id = t.object_id
join sys.indexes i -- get index for constraint
on i.object_id = t.object_id
and i.name = pk.name
join sys.index_columns ik -- index column and name
on ik.object_id = i.object_id
and ik.index_id = i.index_id
and ik.column_id = c.column_id -- vvv Get the right index
where c.name = index_col('[' + s.name + '].[' + t.name + ']', i.index_id, ik.key_ordinal)
and pk.type in ('PK', 'UQ') --probably redundant
order by t.object_id,
pk.object_id,
ik.key_ordinal
-- This generates indexes
--
select case when ik.key_ordinal =
(select min(ik2.key_ordinal)
from sys.index_columns ik2
where ik2.object_id = ik.object_id
and ik2.index_id = ik.index_id)
then 'create ' +
case when is_unique_constraint = 1 then 'unique '
else ''
end +
'index [' + rtrim(i.name) + ']' + char (10) +
' on [' + rtrim(t.name) + ']' + char (10) +
' ('
else ' ,'
end +
'[' + c.name + ']' +
case when ik.key_ordinal =
(select max(ik2.key_ordinal)
from sys.index_columns ik2
where ik2.object_id = ik.object_id
and ik2.index_id = ik.index_id)
then ')' + char(10) + 'go' + char(10)
else ''
end
from sys.objects t -- table
join #objects o
on o.object_id = t.object_id
join sys.columns c -- columns
on c.object_id = t.object_id
join sys.indexes i -- get index for constraint
on i.object_id = t.object_id
join sys.index_columns ik -- index column and name
on ik.object_id = i.object_id
and ik.index_id = i.index_id
and ik.column_id = c.column_id -- vvv Get the right index
where c.name = index_col(t.name, i.index_id, ik.key_ordinal)
and t.type = 'U'
and i.name <> t.name
and i.name not in
(select c2.name
from sys.objects c2
where c2.parent_object_id = t.object_id
and c2.type in ('PK', 'UQ'))
order by t.name,
i.name,
ik.key_ordinal
-- This generates foreign keys
--
select con.constraint_text as [--constraint_text]
from ((select case when kc.constraint_column_id =
(select min(k2.constraint_column_id)
from sys.foreign_key_columns k2
where k2.constraint_object_id = k.object_id)
then 'alter table [' + #schema + '].[' + rtrim(t.name) + ']' + char(10) +
' add constraint [' + rtrim (k.name) + '] ' + char(10) +
' foreign key ('
else ' ,'
end +
'[' + tc.name + ']' +
case when kc.constraint_column_id =
(select max(k2.constraint_column_id)
from sys.foreign_key_columns k2
where k2.constraint_object_id = k.object_id)
then ')'
else ''
end as constraint_text,
t.name as table_name,
k.name as constraint_name,
kc.constraint_column_id as row_order,
t.object_id
from sys.foreign_keys k
join sys.objects t
on t.object_id = k.parent_object_id
join sys.columns tc
on tc.object_id = t.object_id
join sys.foreign_key_columns kc
on kc.constraint_object_id = k.object_id
and kc.parent_object_id = t.object_id
and kc.parent_column_id = tc.column_id
join sys.objects r
on r.object_id = kc.referenced_object_id
join sys.columns rc
on kc.referenced_object_id = rc.object_id
and kc.referenced_column_id = rc.column_id)
union all
(select case when kc.constraint_column_id =
(select min(k2.constraint_column_id)
from sys.foreign_key_columns k2
where k2.constraint_object_id = k.object_id)
then ' references [' + rtrim(r.name) + ']' + char(10) +
' ('
else ' ,'
end +
'[' + rc.name + ']' +
case when kc.constraint_column_id =
(select max(k2.constraint_column_id)
from sys.foreign_key_columns k2
where k2.constraint_object_id = k.object_id)
then ')' + char(10) + 'go' + char(10)
else ''
end as constraint_text,
t.name as table_name,
k.name as constraint_name,
kc.constraint_column_id + 100 as row_order,
t.object_id
from sys.foreign_keys k
join sys.objects t
on t.object_id = k.parent_object_id
join sys.columns tc
on tc.object_id = t.object_id
join sys.foreign_key_columns kc
on kc.constraint_object_id = k.object_id
and kc.parent_object_id = t.object_id
and kc.parent_column_id = tc.column_id
join sys.objects r
on r.object_id = kc.referenced_object_id
join sys.columns rc
on kc.referenced_object_id = rc.object_id
and kc.referenced_column_id = rc.column_id)) con
join #objects o
on con.object_id = o.object_id
order by con.table_name,
con.constraint_name,
con.row_order
Microsoft SQL Server Database Publishing Wizard is a nice GUI that can script out the structure / data / Procs of a SQL Server 2000/2005 db.
http://www.microsoft.com/downloads/details.aspx?FamilyId=56E5B1C5-BF17-42E0-A410-371A838E570A&displaylang=en
Hope this helps
A quick google and hop pointed me to a Stored proc that should be able to help you. Look at My code library more specifically the file generate_inserts.txt to see if it can help you.
Not really a tool, but the start of one! :)
For loading and unloading table data you could also use bcp, Integration Services or BULK INSERT (for the loading portion). This article describes a method to invoke bcp from within a stored procedure.
TOAD for Oracle can do it, so I suspect TOAD for SQL Server will be able to too.

Resources