How to do ALTER TABLE TYPE efficiently
-
11-10-2020 - |
Pergunta
Unlike tables, a table type cannot be altered by a simple command. I need to do the following:
- Rename existing table type
- Create the new table type
- Open each affected objects (i.e. ALTER SP) and execute it again so that the reference to table type will be updated.
But this is a tedious task as there may be many SP to be updated. Is there any easy way/pre-generated script that can automate this process?
Solução
Instead of
Open each affected objects (i.e. ALTER SP) and execute it again so that the reference to table type will be updated
you can just find all the affected objects and refresh them using sp_refreshsqlmodule
.
Here is the code to find the modules:
select object_name(referencing_id)
from sys.sql_expression_dependencies
where referenced_class_desc = 'TYPE' and referenced_entity_name = 'your_table_type_name';
To do refresh of all this objects you can simply generate the commands like this:
select 'sp_refreshsqlmodule ' + quotename( object_name(referencing_id), '''')
from sys.sql_expression_dependencies
where referenced_class_desc = 'TYPE' and referenced_entity_name = 'your_table_type_name';
Make the output to text instead of grid and copy + paste generated rows to SSMS and execute them.
Outras dicas
For some reference, based on @sepupic
's answer, I can further enhance it to be:
-- First, rename existing table type to something else
EXEC sp_rename 'TT_MY_TABLE_TYPE', 'TT_MY_TABLE_TYPE_1'
-- Create the new table type
CREATE TYPE [dbo].[TT_MY_TABLE_TYPE] AS TABLE(
[MY_FIELD] [varchar](20) NULL
)
GO
-- Do a refresh of the SP/views so that the SP/views will refer to the new table type
-- Save the list of dependencies to a temporary table
SELECT 'sp_refreshsqlmodule ' + quotename( object_name(referencing_id), '''') AS SQL_CMD
INTO #TEMPSQL
FROM sys.sql_expression_dependencies
WHERE referenced_class_desc = 'TYPE' and referenced_entity_name = 'TT_MY_TABLE_TYPE';
DECLARE @sql NVARCHAR(1000)
-- Do a loop for the list of dependencies, use dynamic SQL to execute the SQL commands
DECLARE c_Cur CURSOR FOR
SELECT SQL_CMD
FROM #TEMPSQL
OPEN c_Cur
FETCH NEXT FROM c_Cur INTO @sql
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC SP_EXECUTESQL @statement = @sql
FETCH NEXT FROM c_Cur INTO @sql
END
CLOSE c_Cur
DEALLOCATE c_Cur
-- Drop the old table type
DROP TYPE TT_MY_TABLE_TYPE_1
DROP TABLE #TEMPSQL