Arithmetic overflow for smallint where no smallint is present - tsql

DECLARE #SchemaName VARCHAR(100)
DECLARE #TableName VARCHAR(256)
DECLARE #IndexName VARCHAR(256)
DECLARE #ColumnName VARCHAR(100)
DECLARE #is_unique VARCHAR(100)
DECLARE #IndexTypeDesc VARCHAR(100)
DECLARE #FileGroupName VARCHAR(100)
DECLARE #is_disabled VARCHAR(100)
DECLARE #IndexOptions VARCHAR(MAX)
DECLARE #IndexColumnId INT
DECLARE #IsDescendingKey INT
DECLARE #IsIncludedColumn INT
DECLARE #TSQLScripCreationIndex VARCHAR(MAX)
DECLARE #TSQLScripDisableIndex VARCHAR(MAX)
DECLARE CursorIndex CURSOR
FOR
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name ,
ix.name ,
CASE WHEN ix.is_unique = 1 THEN 'UNIQUE '
ELSE ''
END ,
ix.type_desc ,
CASE WHEN ix.is_padded = 1 THEN 'PAD_INDEX = ON, '
ELSE 'PAD_INDEX = OFF, '
END
+ CASE WHEN ix.allow_page_locks = 1 THEN 'ALLOW_PAGE_LOCKS = ON, '
ELSE 'ALLOW_PAGE_LOCKS = OFF, '
END
+ CASE WHEN ix.allow_row_locks = 1 THEN 'ALLOW_ROW_LOCKS = ON, '
ELSE 'ALLOW_ROW_LOCKS = OFF, '
END
+ CASE WHEN INDEXPROPERTY(t.object_id, ix.name, 'IsStatistics') = 1
THEN 'STATISTICS_NORECOMPUTE = ON, '
ELSE 'STATISTICS_NORECOMPUTE = OFF, '
END
+ CASE WHEN ix.ignore_dup_key = 1 THEN 'IGNORE_DUP_KEY = ON, '
ELSE 'IGNORE_DUP_KEY = OFF, '
END + 'SORT_IN_TEMPDB = OFF,DROP_EXISTING = ON' AS IndexOptions ,
ix.is_disabled ,
FILEGROUP_NAME(ix.data_space_id) FileGroupName
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0 --and schema_name(tb.schema_id)= #SchemaName and tb.name=#TableName
AND t.is_ms_shipped = 0
AND t.name <> 'sysdiagrams'
AND t.name = 'LegalEntity'
ORDER BY SCHEMA_NAME(t.schema_id) ,
t.name ,
ix.name
OPEN CursorIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled, #FileGroupName
WHILE ( ##fetch_status = 0 )
BEGIN
DECLARE #IndexColumns VARCHAR(MAX)
DECLARE #IncludedColumns VARCHAR(MAX)
SET #IndexColumns = ''
SET #IncludedColumns = ''
DECLARE CursorIndexColumn CURSOR
FOR
SELECT col.name ,
ixc.is_descending_key ,
ixc.is_included_column
FROM sys.tables tb
INNER JOIN sys.indexes ix ON tb.object_id = ix.object_id
INNER JOIN sys.index_columns ixc ON ix.object_id = ixc.object_id
AND ix.index_id = ixc.index_id
INNER JOIN sys.columns col ON ixc.object_id = col.object_id
AND ixc.column_id = col.column_id
WHERE ix.type > 0
AND ( ix.is_primary_key = 0
OR ix.is_unique_constraint = 0
)
AND SCHEMA_NAME(tb.schema_id) = #SchemaName
AND tb.name = #TableName
AND ix.name = #IndexName
ORDER BY ixc.index_column_id
OPEN CursorIndexColumn
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName, #IsDescendingKey,
#IsIncludedColumn
WHILE ( ##fetch_status = 0 )
BEGIN
IF #IsIncludedColumn = 0
SET #IndexColumns = #IndexColumns + #ColumnName
+ CASE WHEN #IsDescendingKey = 1 THEN ' DESC, '
ELSE ' ASC, '
END
ELSE
SET #IncludedColumns = #IncludedColumns + #ColumnName
+ ', '
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName,
#IsDescendingKey, #IsIncludedColumn
END
CLOSE CursorIndexColumn
DEALLOCATE CursorIndexColumn
SET #IndexColumns = SUBSTRING(#IndexColumns, 1, LEN(#IndexColumns) - 1)
SET #IncludedColumns = CASE WHEN LEN(#IncludedColumns) > 0
THEN SUBSTRING(#IncludedColumns, 1,
LEN(#IncludedColumns) - 1)
ELSE ''
END
-- print #IndexColumns
-- print #IncludedColumns
SET #TSQLScripCreationIndex = ''
SET #TSQLScripDisableIndex = ''
SET #TSQLScripCreationIndex = 'CREATE ' + #is_unique + #IndexTypeDesc
+ ' INDEX ' + QUOTENAME(#IndexName) + ' ON '
+ QUOTENAME(#SchemaName) + '.' + QUOTENAME(#TableName) + '('
+ #IndexColumns + ') '
+ CASE WHEN LEN(#IncludedColumns) > 0
THEN CHAR(13) + 'INCLUDE (' + #IncludedColumns + ')'
ELSE ''
END + CHAR(13) + 'WITH (' + #IndexOptions + ') ON '
+ '[SC_LE]([Id])' + ';'
IF #is_disabled = 1
SET #TSQLScripDisableIndex = CHAR(13) + 'ALTER INDEX '
+ QUOTENAME(#IndexName) + ' ON ' + QUOTENAME(#SchemaName)
+ '.' + QUOTENAME(#TableName) + ' DISABLE;' + CHAR(13)
--print #TSQLScripCreationIndex
--print #TSQLScripDisableIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled,
#FileGroupName
END
CLOSE CursorIndex
DEALLOCATE CursorIndex

The issue here is probably where you call FILEGROUP_NAME() in the SELECT clause of the definition of CursorIndex. As per the MSDN definition, the filegroup_id parameter passed to FILEGROUP_NAME() is of type smallint. I expect you have one or more records in sys.indexes which have a data_space_id value greater than 32,767 (the maximum value which can be stored in a smallint variable).
You can check by running:
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name AS TableName,
ix.name AS IndexName,
ix.data_space_id
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0
AND t.is_ms_shipped = 0
AND ix.data_space_id > 32767
ORDER BY SCHEMA_NAME(t.schema_id),
t.name,
ix.name
This will return any indexes with this problem. I can see two ways to fix your query:
Omit the FILEGROUP_NAME() call from the original cursor definition and subsequent FETCH calls - it doesn't look like you use it for anything later on, so there's no need for it to be included.
Amend the WHERE clause of the original cursor definition to exclude any indexes with data_space_id values greater than 32767. Note that this approach will mean some indexes are not included in your cursor, but these will only be the ones which have been causing it to fail anyway.
As for why SQL Server allows values greater than 32767 in sys.indexes.data_space_id while FILEGROUP_NAME() requires a smallint parameter, I have no idea - maybe someone else can enlighten us on this?

Related

Getting Error With GROUP BY when Converting Query to Dynamic SQL

I'm trying to convert the following query to dynamic SQL to allow for variations:
UPDATE T
SET SumCount = J.SUM
FROM #temp T
JOIN (SELECT Count_99221 + COUNT_99222 + Count_99223 [SUM], t2.userID
FROM #temp t2
GROUP BY t2.userID, Count_99221 + COUNT_99222 + Count_99223
) J ON T.userID = J.UserID
This is what I have for the Dynamic SQL:
DECLARE #sql3 nvarchar(2000) =
'UPDATE T ' +
'SET SumCount = J.SumOfColumns ' +
'FROM #temp T ' +
'JOIN (SELECT ' + #columnSumString + ' [SumOfColumns], t2.userID ' +
'FROM #temp t2 ' +
'GROUP BY t2.userID, ' + #columnSumString +
' ) J ON T.userID = J.UserID'
EXEC sp_executesql #sql3
I am receiving the following error only when I run the query as Dynamic SQL:
Each GROUP BY expression must contain at least one column that is not
an outer reference.
Can somebody help explain why this is happening? I am new to Dynamic SQL so I'm not privy to any limitations for running queries this way.
Thank you in advance.
EDIT:
The variable #columnString is a string made by concatenating several other column names, created in the following way:
DECLARE #Cursor Cursor
DECLARE #code varchar(20)
DECLARE #ID INT
SET #cptCursor = CURSOR FOR
SELECT * FROM dbo.Split(#UserInput,CHAR(44))
OPEN #cptCursor
FETCH NEXT FROM #cptCursor INTO #ID, #code
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #colName varchar(50) = 'Count_' + cast(#code as varchar(10))
DECLARE #sql nvarchar(50) = 'ALTER TABLE #temp ADD ' + #colName + ' int'
EXEC sp_executesql #sql
--Code that adds values to each column that is created.....
SET #columnSumString = #colName + ' + ' + #columnSumString
--SET #columnSumString = #code + ' + ' + #columnSumString
FETCH NEXT FROM #cptCursor INTO #ID, #code
END
CLOSE #Cursor
DEALLOCATE #Cursor
SET #columnSumString = SUBSTRING(#columnSumString,1,LEN(#columnSumString)-2)
SELECT #columnSumString
The user input is a comma separated string. "Count_99221 + COUNT_99222 + Count_99223" is just one example of columns created from the user input "99221, 99222, 99223".
I also realized I was concatenating the #code variable into #columnSumString instead of #colName. Now when I run the query I don't get the error (even though I don't understand how the above error message relates to that mistake) but every value of SumCount is NULL.
IMHO you must re-write your query as follow:
UPDATE #temp
SET SumCount =
(SELECT Count_99221 + COUNT_99222 + Count_99223
FROM #temp t2
WHERE t2.userID = #temp.userID)
So the dynamic SQL will become:
DECLARE #columnString varchar(200)
SET #columnString = Count_99221 + COUNT_99222 + Count_99223
DECLARE #sql3 nvarchar(2000) =
N'UPDATE #temp ' +
'SET SumCount = (SELECT ' + #columnString +
' FROM #temp t2 WHERE t2.userID = #temp.userID)'
EXEC sp_executesql #sql3

Random Number Generator - Create a matrix of random numbers where the values in each row sum to X in T-SQL?

How to generate a matrix of random numbers where the values in each row add up to X in T-SQL?
The solution matrix should be dynamic:
User can specify number of columns to be returned in the result
User can specify number of rows to be returned in the result
Each row must sum to X (eg. 1)
create proc RandomNumberGenerator
(
#rows int
, #cols int
, #rowsumtotal float
)
as
....
First create a UDF...
CREATE FUNCTION [dbo].[_ex_fn_SplitToTable] (#str varchar(5000), #sep varchar(1) = null)
RETURNS #ReturnVal table (n int, s varchar(5000))
AS
/*
Alpha Test
-----------
select * from [dbo].[_ex_fn_SplitToTable_t2]('a b c d e',' ')
*/
BEGIN
if #sep = ' '
begin
set #sep = CHAR(167)
set #str = REPLACE(#str,' ',CHAR(167))
end
declare #str2 varchar(5000)
declare #sep2 varchar(1)
if LEN(ISNULL(#sep,'')) = 0
begin
declare #i int
set #i = 0
set #str2 = ''
declare #char varchar(1)
startloop:
set #i += 1
--print #i
set #char = substring(#str,#i,1)
set #str2 = #str2 + #char + ','
if LEN(#str) <= #i
goto exitloop
goto startloop
exitloop:
set #str2 = left(#str2,LEN(#str2) - 1)
set #sep2 = ','
--print #str2
end
else
begin
set #str2 = #str
set #sep2 = #sep
end
;WITH Pieces(n, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep2, #str2)
UNION ALL
SELECT n + 1, stop + 1, CHARINDEX(#sep2, #str2, stop + 1)
FROM Pieces
WHERE stop > 0
)
insert into #ReturnVal(n,s)
SELECT n,
SUBSTRING(#str2, start, CASE WHEN stop > 0 THEN stop-start ELSE 5000 END) AS s
FROM Pieces option (maxrecursion 32767)
RETURN
END
GO
Then, create this stored proc...
CREATE PROC [dbo].[RandomNumberGenerator]
(
#Pockets int = 6,
#SumTo float = 100,
#i_iterations int = 100
)
/*
ALPHA TEST
----------
exec RandomNumberGenerator 10, 100, 500
*/
AS
if object_id('tempdb..#_Random_00') is not null drop table #_Random_00
declare #columnstring varchar(max) = (SELECT REPLICATE('c ',#Pockets) as Underline)
print #columnstring
if object_id('tempdb..#_Random_columns') is not null drop table #_Random_columns
select s+CONVERT(varchar,dbo.PadLeft(convert(varchar,n),'0',3)) cols
into #_Random_columns
from [dbo].[_ex_fn_SplitToTable](#columnstring,' ') where LEN(s) > 0
-- ===========================
--select * from #_Random_columns
-- ===========================
declare #columns_sql varchar(max)
set #columns_sql =
(
select distinct
stuff((SELECT distinct + cast(cols as varchar(50)) + ' float, '
FROM (
select cols
from #_Random_columns
) t2
--where t2.n = t1.n
FOR XML PATH('')),3,0,'')
from (
select cols
from #_Random_columns
) t1
)
set #columns_sql = LEFT(#columns_sql,LEN(#columns_sql) - 1)
print #columns_sql
declare #sql varchar(max)
set #sql = 'if object_id(''tempdb..##_proctable_Random_01'') is not null drop table ##_proctable_Random_01 '
print #sql
execute(#sql)
set #sql = 'create table ##_proctable_Random_01 (rowid int,' + #columns_sql + ')'
print #sql
execute(#sql)
declare #TotalOfRand float
declare #i_inner int
declare #i_outer int
set #i_outer = 0
start_outer:
set #i_outer = #i_outer + 1
set #i_inner = 0
declare #sumstring varchar(max)
set #sumstring = ''
start_inner:
set #i_inner = #i_inner+1
set #sumstring = #sumstring + CONVERT(varchar, rand()) + ','
if #i_inner >= #Pockets
goto exit_inner
goto start_inner
exit_inner:
set #TotalOfRand = ( select sum(convert(float,s)) from dbo._ex_fn_SplitToTable(#sumstring,',') )
declare #sumstring_quotient varchar(max)
set #sumstring_quotient = replace(#sumstring,',', '/' + Convert(varchar,#TotalOfRand) + '*' + convert(varchar,#SumTo) + ',')
set #sumstring_quotient = LEFT(#sumstring_quotient,len(#sumstring_quotient) - 1)
print #sumstring_quotient
set #sql = '
insert into ##_proctable_Random_01
select
( select count(*) + 1 from ##_proctable_Random_01 ) rowid,' + #sumstring_quotient
execute(#sql)
if #i_outer >= #i_iterations
goto exit_outer
goto start_outer
exit_outer:
select * from ##_proctable_Random_01
drop table ##_proctable_Random_01
GO

How to create view for all tables in database?

I want to make views from all tables already exist in database that’s hard task to catch the tables one by one and make create view XXXX as select * from Table_name .I find something that it is possible with cursor and the code is :
DECLARE #TableName sysname
DECLARE #ColumnCount INT
DECLARE #ColumnID INT
DECLARE #SelectColumn NVARCHAR(500)
DECLARE #sql NVARCHAR(max) = ''
DECLARE QUERYINFO CURSOR FOR
SELECT
t.name AS TableName,
ccount.ColumnCount,
c.column_id AS ColumnID,
CASE WHEN c.column_id <> ccount.ColumnCount
THEN c.name + ', '
ELSE c.name
END AS SelectColumn
FROM sys.tables t
INNER JOIN sys.columns c ON t.object_id=c.object_id
INNER JOIN (
SELECT object_id,COUNT(*) AS ColumnCount
FROM sys.columns
GROUP BY object_id
) ccount ON t.object_id = ccount.object_id
ORDER BY t.Name,c.column_id
OPEN QUERYINFO
FETCH NEXT FROM QUERYINFO INTO #TableName,#ColumnCount,#ColumnID,#SelectColumn
WHILE ##FETCH_STATUS = 0
BEGIN
IF #ColumnID = 1
BEGIN
SET #sql = 'CREATE VIEW v_' + #TableName + ' AS SELECT ' + #SelectColumn
END
ELSE
BEGIN
SET #sql = #sql + #SelectColumn
END
IF #ColumnID = #ColumnCount
BEGIN
SET #sql = #sql + ' FROM ' + #TableName
EXEC sys.sp_executesql #sql
SET #sql = ''
END
FETCH NEXT FROM QUERYINFO INTO #TableName,#ColumnCount,#ColumnID,#SelectColumn
END
CLOSE QUERYINFO
DEALLOCATE QUERYINFO
but it has error and I don't know how solve it
This is what I would do with dynamic SQL; checking first to see if the view exists, then creating it with all of the columns (not by using SELECT * FROM...).
DECLARE #SQL nvarchar(MAX)
SET #SQL = N''
SELECT
#SQL = #SQL +
N'IF EXISTS(SELECT 1 FROM sys.objects WHERE name = N''v_' + t.name + N''' AND type = N''V'') BEGIN DROP VIEW [v_' + t.name + '] END CREATE VIEW [v_' + t.name + N'] AS SELECT ' +
STUFF(
(SELECT N',' + c.name
FROM
sys.columns AS c
WHERE
c.OBJECT_ID = t.OBJECT_ID
ORDER BY
column_id
FOR XML PATH(''), TYPE).value('.',N'nvarchar(max)')
,1,1,N'')
+ N' FROM [' + t.name + N'];'
FROM
sys.tables AS t
EXEC sp_executesql #SQL

Inserting DateTime into datetime field TSQL

I'm trying to call a stored procedure in SQL Server 2012 Express from a C# program, to insert a DateTime data type into a column (which is also datetime).
For some reason, I keep getting errors about "Conversation failed when converting date and/or time from character string."
I've checked the culture settings in my SQL server, which is set to us_english, but the datetime format is the ISO standard.
Here's the code from the stored procedure. The values are exactly how they're passed by the C# app.
USE testdb;
DECLARE #Name NVARCHAR(50) = 'Somename',
#Location NVARCHAR(50) = 'somelocation',
#Date DateTime = '2013-10-11 11:00:05.000'
BEGIN
SET NOCOUNT ON;
SELECT #Name, #Location, #Date
if exists (select name from ComputerHistory where name = #Name)
begin
DECLARE #Query1 NVARCHAR(MAX)
if #Location <> 'disconnected'
begin
set #Query1 = '
update ComputerHistory
set ' + #Location + ' = 1 + ISNULL((select MAX(' + #Location + ') from ComputerHistory where name = ''' + #Name + '''),0),
lastdateonline = ''' + #Date + '''
where name = ''' + #Name + '''
'
--EXEC sp_executesql #Query1
end
else
begin
set #Query1 = '
update ComputerHistory
set ' + #Location + ' = 1 + ISNULL((select MAX(' + #Location + ') from ComputerHistory where name = ''' + #Name + '''),0)
where name = ''' + #Name + '''
'
EXEC sp_executesql #Query1
end
end
else
begin
DECLARE #Query2 NVARCHAR(150)
set #Query2 = 'insert into ComputerHistory(name, ' + #Location + ') VALUES(''' + #Name + ''', ''1'')'
EXEC sp_executesql #Query2
end
END
Try cast(#Date as nvarchar(50))
set #Query1 = '
update ComputerHistory
set ' + #Location + ' = 1 + ISNULL((select MAX(' + #Location + ') from ComputerHistory where name = ''' + #Name + '''),0),
lastdateonline = ''' + cast(#Date as nvarchar(50)) + '''
where name = ''' + #Name + '''
'

Stored proc to get list of tables and stored procs using those tables from all databases

A single stored proc which do the following work: when I pass a column name, I should get a list of all the tables containing that column, and a list of all stored procedures that are using those tables from all databases
DECLARE #rolename AS VARCHAR(200) = 'testx_table'
DECLARE #string1 VARCHAR(2000) = '',
#string2 VARCHAR(2000) = '',
#string3 VARCHAR(2000) = '',
#string4 VARCHAR(2000) = ''
IF #rolename = 'testx_table'
GOTO table_op
IF #rolename = 'testx_proc'
GOTO proc_op
TABLE_OP:
BEGIN
DECLARE #catalog VARCHAR(500),
#schema VARCHAR(50),
#tablename VARCHAR(500),
#tabletype VARCHAR(50)
DECLARE crs_tables CURSOR FOR
SELECT table_catalog,
table_schema,
table_name,
table_type
FROM [INFORMATION_SCHEMA].tables
WHERE table_schema = 'DBO'
OPEN crs_tables
FETCH next FROM crs_tables INTO #catalog, #schema, #tablename,
#tabletype
SELECT #catalog = table_catalog,
#schema = table_schema,
#tablename = table_name,
#tabletype = table_type
FROM [INFORMATION_SCHEMA].tables
WHERE table_schema = 'DBO'
AND #catalog = table_catalog
AND #schema = table_schema
AND #tablename = table_name
AND #tabletype = table_type
SET #string1 = 'GRANT INSERT ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string2 = 'GRANT DELETE ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string3 = 'GRANT UPDATE ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string4 = 'GRANT SELECT ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
EXEC(#string1)
EXEC(#string2)
EXEC(#string3)
EXEC(#string4)
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #catalog = table_catalog,
#schema = table_schema,
#tablename = table_name,
#tabletype = table_type
FROM [INFORMATION_SCHEMA].tables
WHERE table_schema = 'DBO'
AND #catalog = table_catalog
AND #schema = table_schema
AND #tablename = table_name
AND #tabletype = table_type
FETCH next FROM crs_tables INTO #catalog, #schema, #tablename,
#tabletype
SET #string1 = 'GRANT INSERT ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string2 = 'GRANT DELETE ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string3 = 'GRANT UPDATE ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
SET #string4 = 'GRANT SELECT ON ' + '[dbo]' + '.' + #tablename
+ ' TO ' + #rolename
EXEC(#string1)
EXEC(#string2)
EXEC(#string3)
EXEC(#string4)
END
CLOSE crs_tables
DEALLOCATE crs_tables
GOTO EXIT
END
/* */
PROC_OP:
BEGIN
DECLARE #p_catalog VARCHAR(500),
#p_schema VARCHAR(50),
#p_name VARCHAR(500),
#p_type VARCHAR(50),
#xtype VARCHAR(50)
DECLARE crs_routines CURSOR FOR
SELECT r.specific_catalog,
r.specific_schema,
r.specific_name,
r.routine_type,
s.xtype
FROM [INFORMATION_SCHEMA].routines r
INNER JOIN sysobjects s
ON s.NAME = r.specific_name
--and s.xtype = 'FN'
WHERE r.specific_schema = 'DBO'
OPEN crs_routines
FETCH next FROM crs_routines INTO #p_catalog, #p_schema, #p_name,
#p_type,
#xtype
SELECT #p_catalog = r.specific_catalog,
#p_schema = r.specific_schema,
#p_name = r.specific_name,
#p_type = r.routine_type,
#xtype = s.xtype
FROM [INFORMATION_SCHEMA].routines r
INNER JOIN sysobjects s
ON s.NAME = r.specific_name
--and s.xtype = 'FN'
WHERE r.specific_schema = 'DBO'
AND #p_catalog = r.specific_catalog
AND #p_schema = r.specific_schema
AND #p_name = r.routine_name
AND #p_type = r.routine_type
SET #string1 = 'GRANT ' + CASE WHEN #p_type = 'PROCEDURE' OR #xtype =
'FN'
THEN ' EXECUTE '
ELSE ' SELECT' END + ' ON ' + '[dbo]' + '.' + '[' +
#p_name +
']'
+ ' TO ' + #rolename
SET #string2 = 'GRANT ' + ' VIEW DEFINITION ' + ' ON ' + '[dbo]'
+ '.' + '[' + #p_name + ']' + ' TO ' + #rolename
PRINT #string1 + ' / ' + #p_type
EXEC(#string1)
EXEC(#string2)
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #p_catalog = r.specific_catalog,
#p_schema = r.specific_schema,
#p_name = r.specific_name,
#p_type = r.routine_type,
#xtype = s.xtype
FROM [INFORMATION_SCHEMA].routines r
INNER JOIN sysobjects s
ON s.NAME = r.specific_name
--and s.xtype = 'FN'
WHERE r.specific_schema = 'DBO'
AND #p_catalog = r.specific_catalog
AND #p_schema = r.specific_schema
AND #p_name = r.routine_name
AND #p_type = r.routine_type
FETCH next FROM crs_routines INTO #p_catalog, #p_schema, #p_name
,
#p_type,
#xtype
SET #string1 = 'GRANT ' + CASE WHEN #p_type = 'PROCEDURE' OR
#xtype =
'FN'
THEN ' EXECUTE '
ELSE ' SELECT' END + ' ON ' + '[dbo]' + '.' + '['
+
#p_name
+
']'
+ ' TO ' + #rolename
SET #string2 = 'GRANT ' + ' VIEW DEFINITION ' + ' ON ' + '[dbo]'
+ '.' + '[' + #p_name + ']' + ' TO ' + #rolename
PRINT #string1 + ' / ' + #p_type
PRINT #string2 + ' / ' + #p_type
EXEC(#string1)
EXEC(#string2)
END
CLOSE crs_routines
DEALLOCATE crs_routines
GOTO EXIT
END