How to write/append text to the bottom of n SQL script? - sql

I have the need to add/append text(SQL) to the bottom of an existing script.
I have a STORED PROCEDURE that generates INSERT statements for me. They are quit allot, so at the moment i copy and past them in the desired scripts.
This is basically what the SQL looks like:
SELECT '' + CHAR(13) + CHAR(10) + 'EXECUTE [procSystemAppEntity_InsertOrUpdate] ' + CHAR(13) + CHAR(10) + ' #SystemUID = #SystemUID' + CHAR(13) + CHAR(10)
+ ',#SystemAppCode = #SystemAppCode' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityTypeCode = N''' + saet.[SystemAppEntityTypeCode] + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityUID = '''+ CAST((SELECT NEWID()) AS nvarchar(max)) + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityCode = ''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityName = N''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#TableName = N''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#TableKeyColumnName = N''' + tab.name + 'ID''' + CHAR(13) + CHAR(10)
+ ',#TableKeyCodeColumnName = N''' + tab.name + 'Code''' + CHAR(13) + CHAR(10)
+ ',#ManagedAssemblyName = N''' + CASE WHEN #SystemAppEntityManagedAssemblyName IS NULL THEN '' ELSE #SystemAppEntityManagedAssemblyName END + '''' + CHAR(13) + CHAR(10)
+ ', #ManagedNamespace = N''' + CASE WHEN #SystemAppEntityManagedNamespace IS NULL THEN '' ELSE #SystemAppEntityManagedNamespace END + '''' + CHAR(13) + CHAR(10)
+ ', #ManagedClassName = ''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ', #IsMultiple = ' + CAST(#IsMultiple AS varchar(1)) + CHAR(13) + CHAR(10)
+ ', #IsCodeGenerated = 1' + CHAR(13) + CHAR(10)
+ ', #IsActive = 1' + CHAR(13) + CHAR(10)
+ ', #SystemAppUserID = #CreationSystemAppUserID ' + CHAR(13) + CHAR(10) + '; '
FROM sys.tables tab INNER JOIN
[SystemAppEntityType] saet ON saet.[IsMultipleEntity] = CASE WHEN RIGHT(tab.name, 1) = 's' THEN 1 ELSE 0 END AND saet.[IsNavigationEntity] = 0 AND saet.IsSystemEntity = CASE WHEN LEFT(tab.name, 3) = 'Sys' THEN 1 ELSE 0 END
WHERE (tab.name NOT IN (SELECT e.[TableName] FROM [SystemAppEntity] e))
AND (tab.name = #Code)
With an output of:
EXECUTE [procSystemAppEntity_InsertOrUpdate]
#SystemUID = #SystemUID
,#SystemAppCode = #SystemAppCode
,#SystemAppEntityTypeCode = N'App-S'
,#SystemAppEntityUID = '11E347C7-7E69-4555-A6F0-2AFE142FC25F'
,#SystemAppEntityCode = 'Revision'
,#SystemAppEntityName = N'Revision'
,#TableName = N'Revision'
,#TableKeyColumnName = N'RevisionID'
,#TableKeyCodeColumnName = N'RevisionCode'
,#ManagedAssemblyName = N'SomeManagedAssemblyName '
, #ManagedNamespace = N'SomeManagedNamespace '
, #ManagedClassName = 'Revision'
, #IsMultiple = 0
, #IsCodeGenerated = 1
, #IsIntegratedToStaging = 1
, #IsActive = 1
, #SystemAppUserID = #CreationSystemAppUserID
;
That being said, is there a way that i can maybe write/append the Output statements directly to the desired script?
I just want it to add to the bottom of the script. Is this possible and if so, how would i achive this?

SELECT '' + CHAR(13) + CHAR(10) + 'EXECUTE [procSystemAppEntity_InsertOrUpdate] ' + CHAR(13) + CHAR(10) + ' #SystemUID = #SystemUID' + CHAR(13) + CHAR(10)
+ ',#SystemAppCode = #SystemAppCode' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityTypeCode = N''' + saet.[SystemAppEntityTypeCode] + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityUID = '''+ CAST((SELECT NEWID()) AS nvarchar(max)) + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityCode = ''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#SystemAppEntityName = N''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#TableName = N''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ',#TableKeyColumnName = N''' + tab.name + 'ID''' + CHAR(13) + CHAR(10)
+ ',#TableKeyCodeColumnName = N''' + tab.name + 'Code''' + CHAR(13) + CHAR(10)
+ ',#ManagedAssemblyName = N''' + CASE WHEN #SystemAppEntityManagedAssemblyName IS NULL THEN '' ELSE #SystemAppEntityManagedAssemblyName END + '''' + CHAR(13) + CHAR(10)
+ ', #ManagedNamespace = N''' + CASE WHEN #SystemAppEntityManagedNamespace IS NULL THEN '' ELSE #SystemAppEntityManagedNamespace END + '''' + CHAR(13) + CHAR(10)
+ ', #ManagedClassName = ''' + tab.name + '''' + CHAR(13) + CHAR(10)
+ ', #IsMultiple = ' + CAST(#IsMultiple AS varchar(1)) + CHAR(13) + CHAR(10)
+ ', #IsCodeGenerated = 1' + CHAR(13) + CHAR(10)
+ ', #IsActive = 1' + CHAR(13) + CHAR(10)
+ ', #SystemAppUserID = #CreationSystemAppUserID ' + CHAR(13) + CHAR(10) + ';
Insert into table(...) ;'
FROM sys.tables tab INNER JOIN
[SystemAppEntityType] saet ON saet.[IsMultipleEntity] = CASE WHEN RIGHT(tab.name, 1) = 's' THEN 1 ELSE 0 END AND saet.[IsNavigationEntity] = 0 AND saet.IsSystemEntity = CASE WHEN LEFT(tab.name, 3) = 'Sys' THEN 1 ELSE 0 END
WHERE (tab.name NOT IN (SELECT e.[TableName] FROM [SystemAppEntity] e))
AND (tab.name = #Code)

What version of SQL Server are you using?
If you are using SQL Server 2008+ then you can make generate the INSERT scripts via Generate Script utility itself.
In SQL Server 2005 or before (I have tried in SQL 2K also) then there is a pretty good stroed proc which can generate the INSERT script for a given table. Check out http://vyaskn.tripod.com/code/generate_inserts.txt

Related

SQL Server - Get a list of datatypes, max length, if its an identity and if its a primary key without object_ID function

I need a query that gets the datatype, max length, if its an identity and if its a primary key from a specific table_name without the use of the object_id function. So far what I have right now (and also found this somewhere on stackoverflow):
SELECT col.COLUMN_NAME AS ColumnName
, col.DATA_TYPE AS DataType
, col.CHARACTER_MAXIMUM_LENGTH AS MaxLength
, COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsIdentity')AS IS_IDENTITY
, CAST(ISNULL(pk.is_primary_key, 0)AS bit)AS IsPrimaryKey
FROM INFORMATION_SCHEMA.COLUMNS AS col
LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
, o.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, i.is_primary_key
FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.objects AS o ON i.object_id = o.object_id
LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND col.COLUMN_NAME = pk.COLUMN_NAME
WHERE col.TABLE_NAME = 'tbl_users'
ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;
Im using this code for a cursor and when I try to get the value of IS_IDENTITY, its always empty or something. I feel like dynamic sql and cursor don't like the OBJECT_ID function. When I run this query without the cursor and stuff, it works perfectly fine.
FULL CODE:
ALTER Procedure [dbo].[sp_generateUpserts]
#databaseName nvarchar(MAX)
AS
BEGIN
SET NOCOUNT ON
DECLARE #tranState BIT
IF ##TRANCOUNT = 0
BEGIN
SET #tranState = 1
BEGIN TRANSACTION tranState
END
BEGIN TRY
Declare #TABLE_NAME varchar(100)
Declare #COLUMN_NAME varchar(100)
Declare #COLUMN_NAME_WITH_SPACE varchar(100)
Declare #DATA_TYPE varchar(100)
Declare #CHARACTER_MAXIMUM_LENGTH INT
Declare #IS_PK INT
Declare #IS_IDENTITY INT
DECLARE #statement nvarchar(MAX)
SET #statement = N'USE [' + #databaseName + '];
DECLARE cursorUpsert CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
ORDER BY TABLE_NAME'
EXECUTE sp_executesql #statement
DECLARE #use_db nvarchar(max)
DECLARE #generateSpStatement varchar(MAX)
DECLARE #spParameters varchar(MAX) = ''
DECLARE #whereColumns varchar(MAX) = ''
DECLARE #updateStatement varchar(MAX) = ''
DECLARE #insertStatement varchar(MAX) = ''
DECLARE #valueStatement varchar(MAX) = ''
OPEN cursorUpsert
FETCH NEXT FROM cursorUpsert
INTO #TABLE_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #statementColumns nvarchar(MAX)
SET #statementColumns = N'USE [' + #databaseName + '];
DECLARE cursorUpsertColumns CURSOR FOR
SELECT col.COLUMN_NAME
, col.DATA_TYPE
, col.CHARACTER_MAXIMUM_LENGTH
, COLUMNPROPERTY(OBJECT_ID(QUOTENAME(col.TABLE_SCHEMA) + ''.'' + QUOTENAME(col.TABLE_NAME)), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
, CAST(ISNULL(pk.is_primary_key, 0) AS bit) AS IS_PK
FROM INFORMATION_SCHEMA.COLUMNS AS col
LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
, o.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, i.is_primary_key
FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.objects AS o ON i.object_id = o.object_id
LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND col.COLUMN_NAME = pk.COLUMN_NAME
WHERE col.TABLE_NAME = ''' + #TABLE_NAME + '''
ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;'
EXECUTE sp_executesql #statementColumns
OPEN cursorUpsertColumns
FETCH NEXT FROM cursorUpsertColumns
INTO #COLUMN_NAME, #DATA_TYPE, #CHARACTER_MAXIMUM_LENGTH, #IS_IDENTITY, #IS_PK
WHILE ##FETCH_STATUS = 0
BEGIN
-- Parameters for the SP
IF #COLUMN_NAME LIKE '% %'
BEGIN
SET #COLUMN_NAME_WITH_SPACE = #COLUMN_NAME
SET #COLUMN_NAME_WITH_SPACE = REPLACE(#COLUMN_NAME_WITH_SPACE,' ','_')
SET #spParameters = #spParameters + CHAR(13) + '#' + #COLUMN_NAME_WITH_SPACE + ' ' + #DATA_TYPE
END
ELSE
BEGIN
SET #spParameters = #spParameters + CHAR(13) + '#' + #COLUMN_NAME + ' ' + #DATA_TYPE
END
IF #DATA_TYPE IN ('varchar', 'nvarchar', 'char', 'nchar')
BEGIN
IF #CHARACTER_MAXIMUM_LENGTH = '-1'
BEGIN
SET #spParameters = #spParameters + '(MAX)'
END
ELSE
BEGIN
SET #spParameters = #spParameters + '(' + CAST(#CHARACTER_MAXIMUM_LENGTH As Varchar(10)) + ')'
END
END
-- Add a comma after each parameter
SET #spParameters = #spParameters + ', '
IF #COLUMN_NAME IN ('top')
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + '[' + #COLUMN_NAME + '],'
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME + ','
END
ELSE IF #COLUMN_NAME LIKE '% %'
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME_WITH_SPACE + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + '[' + #COLUMN_NAME + ']=#' + #COLUMN_NAME_WITH_SPACE + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + '['+ #COLUMN_NAME + '],'
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME_WITH_SPACE + ','
END
ELSE
BEGIN
IF #IS_IDENTITY != 1
BEGIN
print('YES IDENTITY')
END
-- Add where parameters: ColumnName=#ColumnName AND
SET #whereColumns = #whereColumns + CHAR(32) + #COLUMN_NAME + '=#' + #COLUMN_NAME + ' AND'
-- Add update parameters: column1 = value1, etc.
IF #IS_IDENTITY != 1 OR #IS_PK != 1
BEGIN
SET #updateStatement = #updateStatement + CHAR(32) + #COLUMN_NAME + '=#' + #COLUMN_NAME + ','
END
-- Add insert columns
SET #insertStatement = #insertStatement + CHAR(32) + #COLUMN_NAME + ','
-- Add values
SET #valueStatement = #valueStatement + CHAR(32) + '#' + #COLUMN_NAME + ','
END
FETCH NEXT FROM cursorUpsertColumns
INTO #COLUMN_NAME, #DATA_TYPE, #CHARACTER_MAXIMUM_LENGTH, #IS_IDENTITY, #IS_PK
if ##FETCH_STATUS!=0
begin
-- Last row, remove things
-- Remove the last AND word
SET #whereColumns = left (#whereColumns, len(#whereColumns) -3)
-- Remove the last comma from the parameter
SET #spParameters = left (#spParameters, len(#spParameters) -1)
-- Remove the last comma from the updateStatement
SET #updateStatement = left (#updateStatement, len(#updateStatement) -1)
-- Remove the last comma from the insertStatement
SET #insertStatement = left (#insertStatement, len(#insertStatement) -1)
-- Remove the last comma from the valueStatement
SET #valueStatement = left (#valueStatement, len(#valueStatement) -1)
end
END;
CLOSE cursorUpsertColumns;
DEALLOCATE cursorUpsertColumns;
--- End Cursor Columns
-- Generate the SP
SET #generateSpStatement = 'CREATE Procedure [dbo].[sp_' + #TABLE_NAME + '_upsert]' + #spParameters
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'AS BEGIN' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SET NOCOUNT ON' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #tranState BIT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF ##TRANCOUNT = 0' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'BEGIN' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'SET #tranState = 1' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'set transaction isolation level serializable' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'BEGIN TRANSACTION tranState' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'END' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'BEGIN TRY' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF EXISTS(SELECT 1 FROM ' + #TABLE_NAME + ' WITH (updlock) WHERE' + #whereColumns + ')' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'UPDATE ' + #TABLE_NAME + ' SET' + #updateStatement + ' WHERE ' + #whereColumns + ';' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'ELSE' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'INSERT INTO ' + #TABLE_NAME + ' ('+ #insertStatement + ') VALUES (' + #valueStatement + ');' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF #tranState = 1 AND XACT_STATE() = 1' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) + 'COMMIT TRANSACTION tranState' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END TRY' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13) + 'BEGIN CATCH' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_Message VARCHAR(5000)' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_Severity INT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'DECLARE #Error_State INT' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_Message = ERROR_MESSAGE()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_Severity = ERROR_SEVERITY()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'SELECT #Error_State = ERROR_STATE()' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'IF #tranState = 1 AND XACT_STATE() <> 0' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + CHAR(9) +'ROLLBACK TRANSACTION' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(9) + 'RAISERROR (#Error_Message, #Error_Severity, #Error_State)' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END CATCH' + CHAR(13)
SET #generateSpStatement = #generateSpStatement + CHAR(13)
SET #generateSpStatement = #generateSpStatement + 'END' + CHAR(13)
--print(#generateSpStatement)
-- Reset Variables
SET #generateSpStatement = ''
SET #spParameters = ''
SET #whereColumns = ''
SET #updateStatement = ''
SET #insertStatement = ''
SET #valueStatement = ''
FETCH NEXT FROM cursorUpsert
INTO #TABLE_NAME
END;
CLOSE cursorUpsert;
DEALLOCATE cursorUpsert;
IF #tranState = 1
AND XACT_STATE() = 1
COMMIT TRANSACTION tranState
END TRY
BEGIN CATCH
DECLARE #Error_Message VARCHAR(5000)
DECLARE #Error_Severity INT
DECLARE #Error_State INT
SELECT #Error_Message = ERROR_MESSAGE()
SELECT #Error_Severity = ERROR_SEVERITY()
SELECT #Error_State = ERROR_STATE()
IF #tranState = 1 AND XACT_STATE() <> 0
ROLLBACK TRANSACTION
RAISERROR (#Error_Message, #Error_Severity, #Error_State)
END CATCH
END
I feel like dynamic sql and cursor don't like the OBJECT_ID function.
It has nothing to do with OBJECT_ID but most likely incorrect double qouting when using with dynamic string:
COLUMNPROPERTY(OBJECT_ID(''['' + col.TABLE_SCHEMA + ''].['' + col.TABLE_NAME + '']''), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
Anyway you should avoid manually adding [ and use QUOTENAME instead:
COLUMNPROPERTY(OBJECT_ID(QUOTENAME(col.TABLE_SCHEMA) + ''.'' + QUOTENAME(col.TABLE_NAME)), col.COLUMN_NAME, ''IsIdentity'')AS IS_IDENTITY
It's a common case and it would be really nice if here-strings/text quoting were supported.
Another slightly simpler way of getting this information would be something like..
Declare #Schema SYSNAME = 'dbo'
, #Table SYSNAME= 'Orders'
SELECT
name Column_Name
, system_type_name Data_Type
, max_length Max_Length
, is_identity_column Is_Identity_Column
, ISNULL(c.PK_Column,0) Is_Primary_Key_Column
FROM sys.dm_exec_describe_first_result_set (N'SELECT * FROM '+ #Schema +'.' + #Table, null, 0) r
OUTER APPLY (
SELECT 1 PK_Column
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE s
WHERE OBJECTPROPERTY(OBJECT_ID(s.CONSTRAINT_SCHEMA + '.' + QUOTENAME(s.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND s.TABLE_NAME = #Table
AND s.TABLE_SCHEMA = #Schema
AND r.name COLLATE DATABASE_DEFAULT = s.COLUMN_NAME
) c(PK_Column)
You can put this code inside a function and simply call this function cross applying it with sys.tables catalog view.
The dynamic management view sys.dm_exec_describe_first_result_set has lots of other useful information too.
Lets suppose you create a function like this..
CREATE FUNCTION dbo.fn_get_Column_Info (
#Schema SYSNAME
, #Table SYSNAME)
RETURNS TABLE
AS
RETURN
(
SELECT
name Column_Name
, system_type_name Data_Type
, max_length Max_Length
, is_identity_column Is_Identity_Column
, ISNULL(c.PK_Column,0) Is_Primary_Key_Column
FROM sys.dm_exec_describe_first_result_set (N'SELECT * FROM '+ #Schema +'.' + #Table, null, 0) r
OUTER APPLY (
SELECT 1 PK_Column
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE s
WHERE OBJECTPROPERTY(OBJECT_ID(s.CONSTRAINT_SCHEMA + '.' + QUOTENAME(s.CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
AND s.TABLE_NAME = #Table
AND s.TABLE_SCHEMA = #Schema
AND r.name COLLATE DATABASE_DEFAULT = s.COLUMN_NAME
) c(PK_Column)
);
GO
Then your query to get all the information you need would be as simple as..
SELECT s.name , t.name, f.*
FROM sys.schemas s
INNER JOIN sys.Tables t ON s.schema_id = t.schema_id
CROSS APPLY dbo.fn_get_Column_Info(s.name , t.name) f;
No need for any cursor or dynamic SQL, unless you want to do this for all the databases on a server. But even if you had to do that for all databases it would be a much simpler cursor.

generate DDL script from SQL Server database

How to generate DDL (with Foreign keys, indexes, etc.) script of all tables from SQL Server database using SQL (select/stored procedure/etc.)? i need everything except the data.
I can't use Sql Server Management Studio because i want to use it in a node.js script that will run over linux!
For tables : (you can work as follows)
DECLARE #C VARCHAR(200)
DECLARE C CURSOR FOR
SELECT 'EXEC [DBO].[SP_GETDDL] '''+NAME+'''' FROM SYS.TABLES
OPEN C
FETCH NEXT FROM C INTO #C
WHILE ##FETCH_STATUS=0
BEGIN
EXEC (#C)
FETCH NEXT FROM C INTO #C
END
CLOSE C
DEALLOCATE C
The Procedure is as follows:
CREATE PROCEDURE [dbo].[Sp_getddl] #TBL VARCHAR(255)
AS
BEGIN
SET nocount ON
DECLARE #TBLNAME VARCHAR(200),
#SCHEMANAME VARCHAR(255),
#STRINGLEN INT,
#TABLE_ID INT,
#FINALSQL VARCHAR(max),
#CONSTRAINTSQLS VARCHAR(max),
#CHECKCONSTSQLS VARCHAR(max),
#RULESCONSTSQLS VARCHAR(max),
#FKSQLS VARCHAR(max),
#TRIGGERSTATEMENT VARCHAR(max),
#EXTENDEDPROPERTIES VARCHAR(max),
#INDEXSQLS VARCHAR(max),
#vbCrLf CHAR(2)
SET #vbCrLf = Char(13) + Char(10)
SELECT #SCHEMANAME = Isnull(Parsename(#TBL, 2), 'dbo'),
#TBLNAME = Parsename(#TBL, 1)
SELECT #TABLE_ID = [object_id]
FROM sys.objects
WHERE [type] = 'U'
AND [name] <> 'dtproperties'
AND [name] = #TBLNAME
AND [schema_id] = Schema_id(#SCHEMANAME);
IF Isnull(#TABLE_ID, 0) = 0
BEGIN
SET #FINALSQL = 'Table object [' + #SCHEMANAME + '].['
+ Upper(#TBLNAME)
+ '] does not exist in Database ['
+ Db_name() + ']'
SELECT #FINALSQL;
RETURN 0
END
SELECT #FINALSQL = 'CREATE TABLE [' + #SCHEMANAME + '].['
+ Upper(#TBLNAME) + '] ( '
SELECT #TABLE_ID = Object_id(#TBLNAME)
SELECT #STRINGLEN = Max(Len(sys.columns.[name])) + 1
FROM sys.objects
INNER JOIN sys.columns
ON sys.objects.[object_id] = sys.columns.[object_id]
AND sys.objects.[object_id] = #TABLE_ID;
SELECT #FINALSQL = #FINALSQL + CASE WHEN sys.columns.[is_computed] = 1
THEN
#vbCrLf +
'[' + Upper(
sys.columns.[name]) + '] ' + Space(#STRINGLEN -
Len(sys.columns.[name])) + 'AS ' +
Isnull(CALC.definition, '') ELSE
#vbCrLf + '[' + Upper(sys.columns.[name]) + '] '
+
Space(
#STRINGLEN - Len(sys.columns.[name])) +
Upper(Type_name(sys.columns.[user_type_id])) +
CASE
WHEN
Type_name(sys.columns.[user_type_id]) IN (
'decimal',
'numeric') THEN '(' + CONVERT(
VARCHAR, sys.columns.[precision]) + ',' +
CONVERT(
VARCHAR,
sys.columns.[scale]) + ') ' + Space(6 - Len(
CONVERT(
VARCHAR,
sys.columns.[precision]) + ',' +
CONVERT(VARCHAR, sys.columns.[scale]))) + Space(
2)
-- + SPACE(16 - LEN(TYPE_NAME(sys.columns.[user_type_id])))
+ CASE WHEN Columnproperty ( #TABLE_ID,
sys.columns.[name],
'IsIdentity' ) = 0 THEN ' ' ELSE
' IDENTITY(' +
CONVERT(VARCHAR, Isnull(Ident_seed(#TBLNAME), 1)
)
+
',' +
CONVERT(VARCHAR, Isnull(Ident_incr(#TBLNAME), 1)
)
+
')' END
+ CASE WHEN sys.columns.[is_nullable] = 0 THEN
' NOT NULL'
ELSE ' NULL' END WHEN
Type_name(sys.columns.[user_type_id]) IN (
'float',
'real')
THEN CASE WHEN
sys.columns.[precision] = 53 THEN Space(11 -
Len(CONVERT(VARCHAR, sys.columns.[precision])))
+
Space(7) +
Space(16 -
Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
sys.columns.[is_nullable] = 0 THEN
' NOT NULL' ELSE ' NULL' END ELSE '(' +
CONVERT(
VARCHAR,
sys.columns.[precision]) + ') ' + Space(6 - Len(
CONVERT(
VARCHAR, sys.columns.[precision]))) + Space(7) +
Space
(16
- Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
sys.columns.[is_nullable] = 0 THEN ' NOT NULL'
ELSE
' NULL' END
END WHEN Type_name(sys.columns.[user_type_id])
IN
(
'char',
'varchar') THEN CASE WHEN
sys.columns.[max_length]
=
-1 THEN
'(max)' + Space(6 -
Len(CONVERT(VARCHAR, sys.columns.[max_length])))
+
Space(7) +
Space(16 -
Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
sys.columns.collation_name IS NULL THEN ''
ELSE ' COLLATE ' + sys.columns.collation_name
END
+
CASE WHEN
sys.columns.[is_nullable] = 0 THEN ' NOT NULL'
ELSE
' NULL' END ELSE '(' +
CONVERT(VARCHAR, sys.columns.[max_length]) +
') '
+
Space(6 -
Len(CONVERT(VARCHAR, sys.columns.[max_length])))
+
Space(7) +
Space(16 -
Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
sys.columns.collation_name IS NULL THEN ''
ELSE ' COLLATE ' + sys.columns.collation_name
END
+
CASE WHEN
sys.columns.[is_nullable] = 0 THEN ' NOT NULL'
ELSE
' NULL' END END WHEN
Type_name(sys.columns.[user_type_id]) IN (
'nchar',
'nvarchar'
) THEN CASE WHEN
sys.columns.[max_length] = -1 THEN '(max)' +
Space
(6 -
Len(CONVERT(VARCHAR, (sys.columns.[max_length]))))
+
Space(7)
+ Space(16 - Len(Type_name(
sys.columns.[user_type_id]))) + CASE WHEN
sys.columns.collation_name IS NULL THEN '' ELSE
' COLLATE ' +
sys.columns.collation_name END + CASE WHEN
sys.columns.[is_nullable] = 0 THEN
' NOT NULL' ELSE ' NULL' END ELSE '(' +
CONVERT(
VARCHAR,
(sys.columns.[max_length])) + ') ' + Space(6 - Len
(
CONVERT(
VARCHAR, (sys.columns.[max_length])))) + Space(7)
+
Space(16
- Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
sys.columns.collation_name IS NOT NULL THEN ''
ELSE
' COLLATE ' +
sys.columns.collation_name END + CASE WHEN
sys.columns.[is_nullable]
= 0 THEN ' NOT NULL' ELSE ' NULL' END END WHEN
Type_name(
sys.columns.[user_type_id]) IN ('datetime',
'money',
'text',
'image') THEN Space(18 -
Len(Type_name(sys.columns.[user_type_id]))) +
' ' + CASE WHEN
sys.columns.[is_nullable] = 0 THEN ' NOT NULL'
ELSE
' NULL' END ELSE Space(16
- Len(Type_name(sys.columns.[user_type_id]))) +
CASE
WHEN
Columnproperty ( #TABLE_ID, sys.columns.[name],
'IsIdentity'
) = 0 THEN ' ' ELSE ' IDENTITY(' +
CONVERT(
VARCHAR, Isnull(Ident_seed(#TBLNAME), 1) ) + ',' +
CONVERT(
VARCHAR, Isnull(Ident_incr(#TBLNAME), 1) ) + ')'
END +
Space(
2) + CASE WHEN sys.columns.[is_nullable] = 0 THEN
' NOT NULL'
ELSE ' NULL' END END + CASE WHEN
sys.columns.[default_object_id] = 0 THEN ''
--ELSE ' DEFAULT ' + ISNULL(def.[definition] ,'')
--optional section in case NAMED default cosntraints are needed:
ELSE #vbCrLf + 'CONSTRAINT [' + def.NAME + '] DEFAULT ' +
Isnull(def.[definition], '')
--i thought it needed to be handled differently! NOT!
END --CASE cdefault
END --iscomputed
+ ','
FROM sys.columns
LEFT OUTER JOIN sys.default_constraints DEF
ON sys.columns.[default_object_id] = DEF.[object_id]
LEFT OUTER JOIN sys.computed_columns CALC
ON sys.columns.[object_id] = CALC.[object_id]
AND sys.columns.[column_id] = CALC.[column_id]
WHERE sys.columns.[object_id] = #TABLE_ID
ORDER BY sys.columns.[column_id]
SELECT #STRINGLEN = Max(Len([name])) + 1
FROM sys.objects
DECLARE #Results TABLE
(
[schema_id] INT,
[schema_name] VARCHAR(255),
[object_id] INT,
[object_name] VARCHAR(255),
[index_id] INT,
[index_name] VARCHAR(255),
[rows] INT,
[sizemb] DECIMAL(19, 3),
[indexdepth] INT,
[type] INT,
[type_desc] VARCHAR(30),
[fill_factor] INT,
[is_unique] INT,
[is_primary_key] INT,
[is_unique_constraint] INT,
[index_columns_key] VARCHAR(max),
[index_columns_include] VARCHAR(max)
)
INSERT INTO #Results
SELECT sys.schemas.schema_id,
sys.schemas.[name]
AS schema_name,
sys.objects.[object_id],
sys.objects.[name]
AS object_name,
sys.indexes.index_id,
Isnull(sys.indexes.[name], '---')
AS index_name,
partitions.rows,
partitions.sizemb,
Indexproperty(sys.objects.[object_id], sys.indexes.[name],
'IndexDepth')
AS
IndexDepth,
sys.indexes.type,
sys.indexes.type_desc,
sys.indexes.fill_factor,
sys.indexes.is_unique,
sys.indexes.is_primary_key,
sys.indexes.is_unique_constraint,
Isnull(Index_Columns.index_columns_key, '---')
AS index_columns_key,
Isnull(Index_Columns.index_columns_include, '---')
AS index_columns_include
FROM sys.objects
JOIN sys.schemas
ON sys.objects.schema_id = sys.schemas.schema_id
JOIN sys.indexes
ON sys.objects.[object_id] = sys.indexes.[object_id]
JOIN (SELECT [object_id],
index_id,
Sum(row_count) AS
Rows,
CONVERT(NUMERIC(19, 3), CONVERT(NUMERIC(19, 3), Sum(
in_row_reserved_page_count
+ lob_reserved_page_count
+
row_overflow_reserved_page_count
)) /
CONVERT(NUMERIC(19, 3), 128)) AS
SizeMB
FROM sys.dm_db_partition_stats
GROUP BY [object_id],
index_id) AS partitions
ON sys.indexes.[object_id] = partitions.[object_id]
AND sys.indexes.index_id = partitions.index_id
CROSS apply (SELECT LEFT(index_columns_key,
Len(index_columns_key) - 1)
AS
index_columns_key
,
LEFT(index_columns_include, Len(index_columns_include) - 1) AS
index_columns_include
FROM (SELECT (SELECT sys.columns.[name] + ',' + ' '
FROM sys.index_columns
JOIN sys.columns
ON sys.index_columns.column_id = sys.columns.column_id
AND sys.index_columns.[object_id] =
sys.columns.[object_id]
WHERE sys.index_columns.is_included_column = 0
AND sys.indexes.[object_id] =
sys.index_columns.[object_id]
AND sys.indexes.index_id = sys.index_columns.index_id
ORDER BY key_ordinal
FOR xml path('')) AS index_columns_key,
(SELECT sys.columns.[name] + ',' + ' '
FROM sys.index_columns
JOIN sys.columns
ON sys.index_columns.column_id = sys.columns.column_id
AND sys.index_columns.[object_id] =
sys.columns.[object_id]
WHERE sys.index_columns.is_included_column = 1
AND sys.indexes.[object_id] =
sys.index_columns.[object_id]
AND sys.indexes.index_id = sys.index_columns.index_id
ORDER BY index_column_id
FOR xml path('')) AS index_columns_include) AS Index_Columns) AS
Index_Columns
WHERE sys.schemas.[name] LIKE CASE
WHEN #SCHEMANAME = '' THEN
sys.schemas.[name]
ELSE #SCHEMANAME
END
AND sys.objects.[name] LIKE CASE
WHEN #TBLNAME = '' THEN
sys.objects.[name]
ELSE #TBLNAME
END
ORDER BY sys.schemas.[name],
sys.objects.[name],
sys.indexes.[name]
--#Results table has both PK,s Uniques and indexes in thme...pull them out for adding to funal results:
SET #CONSTRAINTSQLS = ''
SET #INDEXSQLS = ''
SELECT #CONSTRAINTSQLS = #CONSTRAINTSQLS + CASE WHEN is_primary_key = 1 OR
is_unique =
1 THEN #vbCrLf +
'CONSTRAINT [' + index_name + '] ' + Space
(
#STRINGLEN
- Len(index_name)) + CASE WHEN
is_primary_key =
1 THEN
' PRIMARY KEY ' ELSE CASE WHEN is_unique = 1
THEN
' UNIQUE ' ELSE '' END END + type_desc
+
CASE WHEN
type_desc='NONCLUSTERED' THEN '' ELSE ' '
END
+ ' ('
+ index_columns_key + ')' + CASE WHEN
index_columns_include <> '---' THEN
' INCLUDE ('
+
index_columns_include + ')' ELSE '' END +
CASE
WHEN
fill_factor <> 0 THEN ' WITH FILLFACTOR = '
+
CONVERT(
VARCHAR(30), fill_factor) ELSE '' END ELSE
''
END + ','
FROM #RESULTS
WHERE [type_desc] != 'HEAP'
AND is_primary_key = 1
OR is_unique = 1
ORDER BY is_primary_key DESC,
is_unique DESC
SELECT #INDEXSQLS = #INDEXSQLS + CASE WHEN is_primary_key = 0 OR is_unique =
0 THEN
#vbCrLf +
'CREATE INDEX [' + index_name + '] ' + Space(
#STRINGLEN
- Len(index_name)) + ' ON [' + [object_name] +
']' +
' (' +
index_columns_key + ')' + CASE WHEN
index_columns_include <>
'---' THEN ' INCLUDE (' + index_columns_include +
')'
ELSE
'' END + CASE WHEN fill_factor <> 0 THEN
' WITH FILLFACTOR = ' + CONVERT(VARCHAR(30),
fill_factor)
ELSE '' END END
FROM #RESULTS
WHERE [type_desc] != 'HEAP'
AND is_primary_key = 0
AND is_unique = 0
ORDER BY is_primary_key DESC,
is_unique DESC
IF #INDEXSQLS <> ''
SET #INDEXSQLS = #vbCrLf + 'GO' + #vbCrLf + #INDEXSQLS
SET #CHECKCONSTSQLS = ''
SELECT #CHECKCONSTSQLS = #CHECKCONSTSQLS + #vbCrLf
+ Isnull('CONSTRAINT [' + sys.objects.[name] +
'] ' +
Space(
#STRINGLEN - Len(sys.objects.[name])) +
' CHECK ' +
Isnull(sys.check_constraints.definition, '')
+
',', '')
FROM sys.objects
INNER JOIN sys.check_constraints
ON sys.objects.[object_id] =
sys.check_constraints.[object_id]
WHERE sys.objects.type = 'C'
AND sys.objects.parent_object_id = #TABLE_ID
SET #FKSQLS = '';
SELECT #FKSQLS = #FKSQLS + #vbCrLf + 'CONSTRAINT ['
+ Object_name(constid) + ']'
+ Space(#STRINGLEN - Len(Object_name(constid) ))
+ ' FOREIGN KEY (' + Col_name(fkeyid, fkey)
+ ') REFERENCES ' + Object_name(rkeyid) + '('
+ Col_name(rkeyid, rkey) + '),'
FROM sysforeignkeys
WHERE fkeyid = #TABLE_ID
SET #RULESCONSTSQLS = ''
SELECT #RULESCONSTSQLS = #RULESCONSTSQLS
+ Isnull( #vbCrLf +
'if not exists(SELECT [name] FROM sys.objects WHERE TYPE=''R'' AND schema_id = '
+ CONVERT(VARCHAR(30), sys.objects.schema_id) +
' AND [name] = ''[' +
Object_name(sys.columns.[rule_object_id]) + ']'')' +
#vbCrLf +
sys.sql_modules.definition + #vbCrLf + 'GO' + #vbCrLf +
'EXEC sp_binderule ['
+ sys.objects.[name] + '], ''[' +
Object_name(sys.columns.[object_id]) + '].[' +
sys.columns.[name] +
']''' + #vbCrLf + 'GO', '')
FROM sys.columns
INNER JOIN sys.objects
ON sys.objects.[object_id] = sys.columns.[object_id]
INNER JOIN sys.sql_modules
ON sys.columns.[rule_object_id] = sys.sql_modules.[object_id]
WHERE sys.columns.[rule_object_id] <> 0
AND sys.columns.[object_id] = #TABLE_ID
SET #TRIGGERSTATEMENT = ''
SELECT #TRIGGERSTATEMENT = #TRIGGERSTATEMENT + #vbCrLf
+ sys.sql_modules.[definition] + #vbCrLf + 'GO'
FROM sys.sql_modules
WHERE [object_id] IN(SELECT [object_id]
FROM sys.objects
WHERE type = 'TR'
AND [parent_object_id] = #TABLE_ID)
IF #TRIGGERSTATEMENT <> ''
SET #TRIGGERSTATEMENT = #vbCrLf + 'GO' + #vbCrLf + #TRIGGERSTATEMENT
SET #EXTENDEDPROPERTIES = ''
SELECT #EXTENDEDPROPERTIES = #EXTENDEDPROPERTIES + #vbCrLf
+ 'EXEC sys.sp_addextendedproperty #name = N''' + [name]
+ ''', #value = N'''
+ Replace(CONVERT(VARCHAR(max), [value]), '''',
'''''')
+
''', #level0type = N''SCHEMA'', #level0name = ['
+ #SCHEMANAME
+
'], #level1type = N''TABLE'', #level1name = ['
+ #TBLNAME + '];'
FROM Fn_listextendedproperty (NULL, 'schema', #SCHEMANAME, 'table',
#TBLNAME, NULL,
NULL);
IF #EXTENDEDPROPERTIES <> ''
SET #EXTENDEDPROPERTIES = #vbCrLf + 'GO' + #vbCrLf + #EXTENDEDPROPERTIES
SELECT #FINALSQL = #FINALSQL + #CONSTRAINTSQLS + #CHECKCONSTSQLS
+ #FKSQLS
SET #FINALSQL = Substring(#FINALSQL, 1, Len(#FINALSQL) - 1);
SET #FINALSQL = #FINALSQL + ')' + #vbCrLf;
SELECT #FINALSQL + #INDEXSQLS + #RULESCONSTSQLS
+ #TRIGGERSTATEMENT + #EXTENDEDPROPERTIES
END
go
You can use mssql-scripter direct from Microsoft, it is quite new and requires a recent Python runtime... but works on Linux, Macos and Windows
Actually, there is still no way from Microsoft supported today to support this.
But you could do a hack:
With the following PowerShell Script you can call the DDL export via PowerShell:
$server = "MSSQLServer\Instance"
$srcDB = "TestDB"
$dump = "C:\Temp\EE\TestDB.sql"
# Stop on any error
$ErrorActionPreference = "stop"
[void] [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO')
[void] [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SQlServer.SMOExtended')
$xfer = [Microsoft.SqlServer.Management.SMO.Transfer] ([Microsoft.SqlServer.Management.SMO.Server] $server).Databases[$srcDB]
# Set export options.
$opts = New-Object Microsoft.SqlServer.Management.SMO.ScriptingOptions
$opts.Filename = $dump
$opts.ToFileOnly = $true
$opts.AllowSystemObjects = $false
$opts.Statistics = $false
$opts.ScriptDataCompression = $false
$xfer.options = $opts
$xfer.ScriptTransfer()
Now just save this script and all it via TSQL - take a look here: call PowerShell via T-SQL
... and then read the temp file with OPENROWSET(BULK ..., SINGLE_CLOB)

AS NewCompoundField - Concatenating values which may be NULL

I have the following T-SQL query;
SELECT
Site.Address1 + CHAR(13) + Site.Address2 + CHAR(13) +
Site.Address3 + CHAR(13) + Site.Town + CHAR(13) +
Site.eCounty AS SiteAddress
FROM Site
If any of the Site.AddressX fields making up SiteAddress are NULL, then SiteAddress is itself NULL. I would like a Site.AddressX field and it's following new line character to be ignored if it is NULL.
I have tried adding a CASE statement for a single field and it's new line character, but have not been able to get it to work.
SELECT
(CASE WHEN (Site.Address1 IS NULL) THEN '' ELSE Site.Address1 + CHAR(10)) +
Site.Address2 + CHAR(13) +
Site.Address3 + CHAR(13) + Site.Town + CHAR(13) +
Site.eCounty AS SiteAddress
FROM Site
How might I go about doing this?
Try this:
SELECT
COALESCE([Site].Address1 + CHAR(13), '') +
COALESCE([Site].Address2 + CHAR(13), '') +
COALESCE([Site].Address3 + CHAR(13), '') +
COALESCE([Site].Town + CHAR(13), '') +
[Site].eCounty AS SiteAddress
FROM [Site]
Try this
SELECT
CASE WHEN Site.Address1 IS NULL THEN ''
ELSE Site.Address1 + CHAR(10) +
Site.Address2 + CHAR(13) +
Site.Address3 + CHAR(13) + Site.Town + CHAR(13) +
Site.eCounty END AS SiteAddress
FROM SITE Site

Dynamically Generate TVP from an existing table?

Is there is a way to generate a TVP from an existing table? I have tried this, https://dba.stackexchange.com/questions/12596/using-tables-as-table-valued-parameters-tvp but it's showing me syntax error?
-- you would pass these two in as parameters of course:
DECLARE
#TableName SYSNAME = N'LocationTable',
#TypeName SYSNAME = N'LocationTypeTable';
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql = #sql + N',' + CHAR(13) + CHAR(10) + CHAR(9)
+ QUOTENAME(c.name) + ' '
+ s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN
'(' + CONVERT(VARCHAR(12), (c.max_length/
(CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END)) + ')'
ELSE '' END
-- need much more conditionals here for other data types
FROM sys.columns AS c
INNER JOIN sys.types AS s
ON c.system_type_id = s.system_type_id
AND c.user_type_id = s.user_type_id
WHERE c.[object_id] = OBJECT_ID(#TableName);
SELECT #sql = N'CREATE TYPE ' + #TypeName
+ ' AS TABLE ' + CHAR(13) + CHAR(10) + (' + STUFF(#sql, 1, 1, '')
+ CHAR(13) + CHAR(10) + ');';
PRINT #sql;
-- EXEC sp_executesql #sql;
I have made modifications to your code above. This code executes but returns no values. What are you looking for exactly.
-- you would pass these two in as parameters of course:
DECLARE
#TableName SYSNAME
Set #TableName = N'LocationTable'
DECLARE
#TypeName SYSNAME
Set #TypeName = N'LocationTypeTable'
DECLARE #sql NVARCHAR(4000)
SET #sql= N'';
SELECT #sql = N',' + CHAR(13) + CHAR(10) + CHAR(9)
+ QUOTENAME(c.name) + ' '
+ s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN
-- '(' +
CONVERT(VARCHAR(12), (c.max_length/
(CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END)))
-- + ')'
ELSE '' END
-- need much more conditionals here for other data types
FROM sys.columns AS c
INNER JOIN sys.types AS s
ON c.system_type_id = s.system_type_id
AND c.user_type_id = s.user_type_id
WHERE c.[object_id] = OBJECT_ID(#TableName);
SELECT #sql = N'CREATE TYPE ' + #TypeName
+ ' AS TABLE ' + CHAR(13) + CHAR(10) + '(' + STUFF(#sql, 1, 1, '')
+ CHAR(13) + CHAR(10) + ');';
PRINT #sql;
-- EXEC sp_executesql #sql;

How do I generate CRUD stored procedures from a table in SQL Server Management Studio

How do I take a table, and auto-gen CRUD stored procs for it in SSMS?
SSMS doesn't have the capability to generate CRUD procedures. You can generate INSERT, UPDATE statements etc. by right-clicking, Script Table As > but I think you will have better luck with Mladen Prajdic's SSMS Tools Pack.
If you are using Visual Studio you can do it: http://weblogs.asp.net/stevewellens/archive/2009/12/11/automatically-generate-stored-procedures-with-visual-studio.aspx
I have a simple TSQL script I use to do mine. It's basic but easily modified to suit your needs. It generates TSQL for an Upsert, Select, and Delete Procedure using table & view you specify.
/*
This is a simple, single-table CRUD Generator. It does not have a bunch of
bells and whistles, and is easy to follow and modify. I wrote this to make
my job easier, and I am sharing it with you to do with it as you wish.
The Basics:
The TSQL below will create 3 procedures:
1. An Upsert Procedure: Suffix _ups
2. A Select Procedure: Suffix _sel
3. A Delete Procedure: Suffix _del
A Little More Detail:
Things you should know:
All 3 procedures have a parameter called #MyID which is used to set
the Context, so that my audit procedures get the validated user. If you
Have no use for it, you'll need to remove the piece of generator code
that adds it as a parameter to each of the 3 procedures. You will also
need to remove the PRINT statement for each procedure that looks like:
PRINT N' SET CONTEXT_INFO #MyID;' + CHAR(13) + CHAR(10)
This generator expects to perform inserts, updates, and deletes on a
table, and selects from a view. If you want to perform selects directly
from the table, simply use the table name in both #TableName and
#ViewName.
The Upsert Procedure:
If ID (Primary Key) is supplied it will perform an Update. Otherwise it
will perform an Insert. This generator is hard-coded to avoid inserting
or updating these particular fields:
Created
CreatedBy
Modified
ModifiedBy
RowVersion
<The Primary Key Field>
That's because in my databases I use those field names for audit, and they
are never modified except internally within the database. You can modify
the part of this procedure that performs this function to suit your needs.
This generator always uses the Parameter name #ID to represent the Primary
key defined for the table. This is my preference but you can modify to suit.
The Select Procedure:
If ID (Primary Key) is supplied it will select a single row from the View
(Table) whose name you provide. Otherwise it will select all rows. If the
#ISACTIVE_SEL variable is set to 1 (True), then the Select Procedure expects
your View (Table) to have a bit-type field named 'IsActive'. My tables are
standardized to this. If #ISACTIVE_SEL = 1 the Select Procedure will have an
additional parameter called #IsActive (bit). When #ID is not supplied, and
#IsActive is not supplied, the procedure selects all rows. When #ID is not
supplied, and #IsActive is supplied, the procedure selects all rows where
the field IsActive matches the parameter #IsActive
The Delete Procedure:
The Delete Pocedure requires that the Key value and the RowVersion value
be supplied. I use an Int type RowVersion, so if you use TimeStamp (varbinary(128))
then you will need to tweak the generator.
--Casey W Little
--Kaciree Software Solutions, LLC
Version 1.00
*/
--Type Your Database Name in this Use statement:
USE [<Your Database>]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*MODIFY THE VALUES BELOW TO SUIT YOUR NEEDS*/
DECLARE #DBName nvarchar(100)=N'<Your Database>';
DECLARE #ProcName nvarchar(100)=N'<Your Proc Name>';
DECLARE #DBRoleName nvarchar(100)=N'<Role that should have exec Rights>';
DECLARE #TableName nvarchar(100)=N'<Your Table Name>';
DECLARE #ViewName nvarchar(100)=N'<Your View Name>';
DECLARE #OrderBy nvarchar(100)=N'<Your Field Name>';
DECLARE #OrderByDir nvarchar(4)=N'ASC';
DECLARE #AUTHOR nvarchar(50) ='<Your Name & Company>';
DECLARE #DESC nvarchar(100) ='<Proc Information>'; -- Ex. 'User Data' will return 'Description : Upsert User Data'
DECLARE #ISACTIVE_SEL bit =0; --Set to 1 if your table has a Bit field named IsActive
/*DO NOT MODIFY BELOW THIS LINE!!!*/
DECLARE #NNND char(23) ='NOT_NULLABLE_NO_DEFAULT';
DECLARE #NNWD char(22) ='NOT_NULLABLE_W_DEFAULT';
DECLARE #NBLE char(8) ='NULLABLE';
DECLARE #LEGEND nvarchar(max);
DECLARE #PRIMARY_KEY nvarchar(100);
--Set up Legend
SET #LEGEND = N'USE [' + #DBName + N'];' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'GO' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'SET ANSI_NULLS ON' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'GO' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'SET QUOTED_IDENTIFIER ON' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'GO' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'-- ===================================================================' + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'-- Author : ' + #AUTHOR + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'-- Create date : ' + CONVERT(nvarchar(30),GETDATE(),101) + CHAR(13) + CHAR(10)
SET #LEGEND = #LEGEND + N'-- Revised date: ' + CHAR(13) + CHAR(10)
--Get Primary Key Field
SELECT TOP 1 #PRIMARY_KEY = COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1 AND TABLE_NAME = #TableName AND TABLE_CATALOG = #DBName;
DECLARE TableCol Cursor FOR
SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE, c.CHARACTER_MAXIMUM_LENGTH
, IIF(c.COLUMN_NAME='RowVersion',#NBLE,IIF(c.COLUMN_NAME=#PRIMARY_KEY,#NBLE,IIF(c.IS_NULLABLE = 'NO' AND c.COLUMN_DEFAULT IS NULL,#NNND,IIF(c.IS_NULLABLE = 'NO' AND c.COLUMN_DEFAULT IS NOT NULL,#NNWD,#NBLE)))) AS [NULLABLE_TYPE]
FROM INFORMATION_SCHEMA.Columns c INNER JOIN
INFORMATION_SCHEMA.Tables t ON c.TABLE_NAME = t.TABLE_NAME
WHERE t.Table_Catalog = #DBName
AND t.TABLE_TYPE = 'BASE TABLE'
AND t.TABLE_NAME = #TableName
ORDER BY [NULLABLE_TYPE], c.ORDINAL_POSITION;
DECLARE #TableSchema varchar(100), #cTableName varchar(100), #ColumnName varchar(100);
DECLARE #DataType varchar(30), #CharLength int, #NullableType varchar(30);
DECLARE #PARAMETERS nvarchar(max);
DECLARE #INSERT_FIELDS nvarchar(max),#INSERT_VALUES nvarchar(max);
DECLARE #UPDATE_VALUES nvarchar(max);
SET #PARAMETERS ='#MyID int,';
SET #INSERT_FIELDS ='';
SET #INSERT_VALUES ='';
SET #UPDATE_VALUES ='';
-- open the cursor
OPEN TableCol
-- get the first row of cursor into variables
FETCH NEXT FROM TableCol INTO #TableSchema, #cTableName, #ColumnName, #DataType, #CharLength, #NullableType
WHILE ##FETCH_STATUS = 0
BEGIN
IF #ColumnName NOT IN('Created','CreatedBy','Modified','ModifiedBy')
BEGIN
SET #PARAMETERS=#PARAMETERS + '#' + IIF(#ColumnName=#PRIMARY_KEY,'ID',#ColumnName) + ' ' + iif(#CharLength IS NULL,#DataType,#DataType + '(' +
CAST(#CharLength AS nvarchar(10)) + ')') + IIF(#NullableType=#NNND OR #NullableType=#NNWD,',','=NULL,');
IF #ColumnName <> #PRIMARY_KEY AND #ColumnName <> N'RowVersion'
BEGIN
SET #INSERT_FIELDS=#INSERT_FIELDS + '[' + #ColumnName + '],';
SET #INSERT_VALUES=#INSERT_VALUES + '#' + IIF(#ColumnName=#PRIMARY_KEY,'ID',#ColumnName) + ',';
SET #UPDATE_VALUES=#UPDATE_VALUES + '[' + #ColumnName + ']=#' + IIF(#ColumnName=#PRIMARY_KEY,'ID',#ColumnName) + ',';
END
END
FETCH NEXT FROM TableCol INTO #TableSchema, #cTableName, #ColumnName, #DataType, #CharLength, #NullableType
END;
SET #PARAMETERS=LEFT(#PARAMETERS,LEN(#PARAMETERS)-1)
SET #INSERT_FIELDS=LEFT(#INSERT_FIELDS,LEN(#INSERT_FIELDS)-1)
SET #INSERT_VALUES=LEFT(#INSERT_VALUES,LEN(#INSERT_VALUES)-1)
SET #UPDATE_VALUES=LEFT(#UPDATE_VALUES,LEN(#UPDATE_VALUES)-1)
-- ----------------
-- clean up cursor
-- ----------------
CLOSE TableCol;
DEALLOCATE TableCol;
--Print Upsert Statement
PRINT N'/****** Object: StoredProcedure [dbo].[' + #ProcName + '_ups] Script Date: ' + CAST(GETDATE() AS nvarchar(30)) + ' ******/' + CHAR(13) + CHAR(10)
PRINT #LEGEND;
PRINT N'-- Description : Upsert ' + #DESC + CHAR(13) + CHAR(10)
PRINT N'-- ===================================================================' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
PRINT N'CREATE PROCEDURE [dbo].[' + #ProcName + '_ups]' + CHAR(13) + CHAR(10);
PRINT N' (' + #PARAMETERS + N')' + CHAR(13) + CHAR(10);
PRINT N'AS' + CHAR(13) + CHAR(10)
PRINT N'BEGIN' + CHAR(13) + CHAR(10)
PRINT N' SET CONTEXT_INFO #MyID;' + CHAR(13) + CHAR(10)
PRINT N' IF #ID IS NULL OR #ID = 0' + CHAR(13) + CHAR(10)
PRINT N' BEGIN' + CHAR(13) + CHAR(10)
PRINT N' INSERT INTO [dbo].[' + #TableName + ']' + CHAR(13) + CHAR(10)
PRINT N' (' + #INSERT_FIELDS + N')' + CHAR(13) + CHAR(10)
PRINT N' VALUES' + CHAR(13) + CHAR(10)
PRINT N' (' + #INSERT_VALUES + N');' + CHAR(13) + CHAR(10)
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] WHERE [ID] = SCOPE_IDENTITY();' + CHAR(13) + CHAR(10)
PRINT N' END' + CHAR(13) + CHAR(10)
PRINT N' ELSE' + CHAR(13) + CHAR(10)
PRINT N' BEGIN' + CHAR(13) + CHAR(10)
PRINT N' UPDATE [dbo].[' + #TableName + ']' + CHAR(13) + CHAR(10)
PRINT N' SET ' + #UPDATE_VALUES + CHAR(13) + CHAR(10)
PRINT N' WHERE ([' + #PRIMARY_KEY + '] = #ID) AND ([RowVersion] = #RowVersion);' + CHAR(13) + CHAR(10)
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] WHERE [ID] = #ID;' + CHAR(13) + CHAR(10)
PRINT N' END' + CHAR(13) + CHAR(10)
PRINT N'END' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
----Now add GRANT and DENY permissions to the Role
PRINT N'GRANT EXECUTE ON [dbo].[' + #ProcName + '_ups] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT N'DENY VIEW DEFINITION ON [dbo].[' + #ProcName + '_ups] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
--Print Select Statement
PRINT N'/****** Object: StoredProcedure [dbo].[' + #ProcName + '_sel] Script Date: ' + CAST(GETDATE() AS nvarchar(30)) + ' ******/' + CHAR(13) + CHAR(10)
PRINT #LEGEND;
PRINT N'-- Description : Select ' + #DESC + CHAR(13) + CHAR(10)
PRINT N'-- ===================================================================' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
PRINT N'CREATE PROCEDURE [dbo].[' + #ProcName + '_sel]' + CHAR(13) + CHAR(10);
PRINT N' (#MyID int, #ID int=NULL' + IIF(#ISACTIVE_SEL = 1,', #IsActive bit=NULL','') + ')' + CHAR(13) + CHAR(10);
PRINT N'AS' + CHAR(13) + CHAR(10)
PRINT N'BEGIN' + CHAR(13) + CHAR(10)
PRINT N' SET CONTEXT_INFO #MyID;' + CHAR(13) + CHAR(10)
PRINT N' IF #ID IS NULL OR #ID = 0' + CHAR(13) + CHAR(10)
IF #ISACTIVE_SEL = 1
BEGIN
PRINT N' BEGIN' + CHAR(13) + CHAR(10)
PRINT N' IF #IsActive IS NULL' + CHAR(13) + CHAR(10)
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] ORDER BY [' + #OrderBy + '] ' + #OrderByDir + ';' + CHAR(13) + CHAR(10)
PRINT N' ELSE' + CHAR(13) + CHAR(10)
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] WHERE [isActive] = #IsActive ORDER BY [' + #OrderBy + '] ' + #OrderByDir + ';' + CHAR(13) + CHAR(10)
PRINT N' END' + CHAR(13) + CHAR(10)
END
ELSE
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] ORDER BY [' + #OrderBy + '] ' + #OrderByDir + ';' + CHAR(13) + CHAR(10)
PRINT N' ELSE' + CHAR(13) + CHAR(10)
PRINT N' SELECT * FROM [dbo].[' + #ViewName + '] WHERE [ID] = #ID;' + CHAR(13) + CHAR(10)
PRINT N'END' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
----Now add GRANT and DENY permissions to the Role
PRINT N'GRANT EXECUTE ON [dbo].[' + #ProcName + '_sel] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT N'DENY VIEW DEFINITION ON [dbo].[' + #ProcName +'_sel] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
--Print Delete Statement
PRINT N'/****** Object: StoredProcedure [dbo].[' + #ProcName + '_del] Script Date: ' + CAST(GETDATE() AS nvarchar(30)) + ' ******/' + CHAR(13) + CHAR(10)
PRINT #LEGEND;
PRINT N'-- Description : Delete ' + #DESC + CHAR(13) + CHAR(10)
PRINT N'-- ===================================================================' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
PRINT N'CREATE PROCEDURE [dbo].[' + #ProcName + '_del]' + CHAR(13) + CHAR(10);
PRINT N' (#MyID int, #ID int, #RowVersion int)' + CHAR(13) + CHAR(10);
PRINT N'AS' + CHAR(13) + CHAR(10)
PRINT N'BEGIN' + CHAR(13) + CHAR(10)
PRINT N' SET CONTEXT_INFO #MyID;' + CHAR(13) + CHAR(10)
PRINT N' SET NOCOUNT ON;' + CHAR(13) + CHAR(10)
PRINT N' DELETE FROM [dbo].[' + #TableName + '] WHERE [' + #PRIMARY_KEY + ']=#ID AND [RowVersion]=#RowVersion;' + CHAR(13) + CHAR(10)
PRINT N' SELECT ##ROWCOUNT as [Rows Affected];' + CHAR(13) + CHAR(10)
PRINT N'END' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT CHAR(13) + CHAR(10)
----Now add GRANT and DENY permissions to the Role
PRINT N'GRANT EXECUTE ON [dbo].[' + #ProcName + '_del] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
PRINT N'DENY VIEW DEFINITION ON [dbo].[' + #ProcName +'_del] TO [' + #DBRoleName + ']' + CHAR(13) + CHAR(10)
PRINT N'GO' + CHAR(13) + CHAR(10)
Beside tools mentioned before, there is another free tool you can use to get the job done in a few clicks.
To do so, you need to enter prefix and suffix in the ApexSQL Complete options window, where you can choose one of the sub-tabs for each of CRUD procedure templates (Select, Insert, Update, Delete). After this is done, the CRUD procedures feature will be available by right clicking in the Object Explorer window, in database or table in the drop down menu.
Here is an article with more details about this functionality (article is a bit old though, as feature is added into the current release)
You can generate four CRUD procedures using a predefined templates from the selected table. This functionality is available in several add-ins, such as SSMS Toolpack and SQL Complete.
CREATE PROCEDURE SP_USUARIO
#usuario varchar(30)=null,
#clave varchar(500)=null,
#idPersona int=null,
#idRol int=null,
#idUsuario int=null,
#TIPO TINYINT=1
AS
BEGIN
IF #TIPO=1 -- LISTAR PERSONAS
BEGIN
SELECT idPersona,Nombre,ApePaterno,ApeMaterno,DNI,Direccion,celular,email FROM Persona
END
IF #TIPO=2 -- LISTAR ROLES
BEGIN
SELECT idRol,Nombre,Descripcion FROM ROL
END
IF #TIPO=3 -- LISTAR USUARIOS
BEGIN
SELECT idUsuario,usuario,pass,idPersona,idRol from Usuario
END
IF #TIPO=3 -- USUARIOS
BEGIN
SELECT idUsuario,usuario,pass,idPersona,idRol from Usuario where idUsuario=#idUsuario
END
IF #TIPO=4 -- AGREGAR USUARIO
BEGIN
INSERT Usuario(usuario,pass,idPersona,idRol) values(#usuario,#clave,#idPersona,#idRol)
END
IF #TIPO=5 -- EDITAR USUARIO
BEGIN
UPDATE Usuario SET usuario=#usuario,pass=#clave,#idPersona=#idPersona,idRol=#idRol where idUsuario=#idUsuario
END
IF #TIPO=6 -- ELIMINAR USUARIO
BEGIN
DELETE Usuario WHERE idUsuario=#idUsuario
END
END
go
-- Here end end of the procedure (started on another post)
If (LEN(#ColumnParametersInsert)>0)
Begin
Set #ColumnParametersInsert = LEFT(#ColumnParametersInsert,LEN(#ColumnParametersInsert)-3) ;
SET #LastPosOfComma = LEN(#ColumnParametersInsertForExec) - CHARINDEX(' ,',REVERSE(#ColumnParametersInsertForExec))
SET #ColumnParametersInsertForExec = LEFT(#ColumnParametersInsertForExec,#LastPosOfComma+3) + SUBSTRING(#ColumnParametersInsertForExec,#LastPosOfComma+5,40000);
Set #ColumnParametersDelete = LEFT(#ColumnParametersDelete,LEN(#ColumnParametersDelete)-4) ;
SET #LastPosOfComma = LEN(#ColumnParametersDeleteForExec) - CHARINDEX(' ,',REVERSE(#ColumnParametersDeleteForExec))
SET #ColumnParametersDeleteForExec = LEFT(#ColumnParametersDeleteForExec,#LastPosOfComma+3) + SUBSTRING(#ColumnParametersDeleteForExec,#LastPosOfComma+5,40000);
SET #ColumnParametersList = LEFT(#ColumnParametersList,LEN(#ColumnParametersList)-3) ;
SET #LastPosOfComma = LEN(#ColumnParametersListForExec) - CHARINDEX(' ,',REVERSE(#ColumnParametersListForExec))
SET #ColumnParametersListForExec = LEFT(#ColumnParametersListForExec,#LastPosOfComma+3) + SUBSTRING(#ColumnParametersListForExec,#LastPosOfComma+5,40000);
IF LEN(#ColumnInValueForInsert)>0
Set #ColumnInValueForInsert = LEFT(#ColumnInValueForInsert,LEN(#ColumnInValueForInsert)-3) ;
IF LEN(#ColumnDefForInsert)>0
Set #ColumnDefForInsert = LEFT(#ColumnDefForInsert,LEN(#ColumnDefForInsert)-3) ;
IF LEN(#tableCols)>0
Set #tableCols = LEFT(#tableCols,LEN(#tableCols)-1) ;
IF LEN(#updCols)>0
Set #updCols = LEFT(#updCols,LEN(#updCols)-3) ;
SET #tableColumnForWhereInListVariables = LEFT(#tableColumnForWhereInListVariables,LEN(#tableColumnForWhereInListVariables)-3)
SET #tableColumnForWhereInListAffectVariables = LEFT(#tableColumnForWhereInListAffectVariables,LEN(#tableColumnForWhereInListAffectVariables)-3) ;
END
If (LEN(#whereCols)>0)
Set #whereCols = 'WHERE ' + LEFT(#whereCols,LEN(#whereCols)-4) ;
ELSE
Set #whereCols = 'WHERE 1=0 --Too dangerous to do update or delete on all the table'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Author : ' + SYSTEM_USER
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Create date : ' + Convert(varchar(20),Getdate())
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Description : Insert Procedure for ' + #CurrentTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'IF OBJECT_ID(''' + REPLACE(#insertSPName,'''','''''') + ''',''P'') IS NOT NULL'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ' DROP PROCEDURE ' + #insertSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'CREATE PROCEDURE ' + #insertSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + '' + #ColumnParametersInsert
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strBegin
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans + 'INSERT INTO ' + #CurrentFullTableName + '('
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans + ' ' + '' + #ColumnDefForInsert + ')'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans + 'VALUES ('
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans + ' ' + '' + #ColumnInValueForInsert + ')'
IF #NbPrimaryKey =1 --No return if 2 or 0 primarykeys
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans + 'SELECT SCOPE_IDENTITY() AS ' + #LastPrimaryKey
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strEnd
Set #strSPText = #strSPText + #SetVariablesForExec
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'EXEC ' + #insertSPName + ' ' + #ColumnParametersInsertForExec
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'SELECT * FROM ' + #CurrentFullTableName + ' ORDER BY 1 DESC'
IF #UnCommentExecForDebug = 0 Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '*/'
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES (#CurrentFullTableName,'Insert',#strSPText)
Set #strSPText = ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Author : ' + SYSTEM_USER
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Create date : ' + Convert(varchar(20),Getdate())
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Description : Update Procedure for ' + #CurrentTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'IF OBJECT_ID(''' + REPLACE(#updateSPName,'''','''''') + ''',''P'') IS NOT NULL'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ' DROP PROCEDURE ' + #updateSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'CREATE PROCEDURE ' + #updateSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + '' + #ColumnParametersUpdate
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strBegin
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans+ 'UPDATE ' + #CurrentFullTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans+ ' SET ' + #updCols
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #spaceForTrans+ ' ' + #whereCols
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strEnd
Set #strSPText = #strSPText + #SetVariablesForExec + #SetVariablesForExecUpdate
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'EXEC ' + #updateSPName + ' ' + #ColumnParametersUpdateForExec
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'SELECT * FROM ' + #CurrentFullTableName + ' '
IF #UnCommentExecForDebug = 0 Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '*/'
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES (#CurrentFullTableName,'Update',#strSPText)
Set #strSPText = ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Author : ' + SYSTEM_USER
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Create date : ' + Convert(varchar(20),Getdate())
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Description : Delete Procedure for ' + #CurrentTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'IF OBJECT_ID(''' + REPLACE(#deleteSPName,'''','''''') + ''',''P'') IS NOT NULL'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ' DROP PROCEDURE ' + #deleteSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'CREATE PROCEDURE ' + #deleteSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + '' + #ColumnParametersDelete
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strBegin
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + 'DELETE FROM ' + #CurrentFullTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' ' + #whereCols
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strEnd
Set #strSPText = #strSPText + #SetVariablesForExecDelete
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'EXEC ' + #deleteSPName + ' ' + #ColumnParametersDeleteForExec
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'SELECT * FROM ' + #CurrentFullTableName + ' ORDER BY 1 DESC'
IF #UnCommentExecForDebug = 0 Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '*/'
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES (#CurrentFullTableName,'Delete',#strSPText)
Set #strSPText = ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Author : ' + SYSTEM_USER
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Create date : ' + Convert(varchar(20),Getdate())
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- Description : List Procedure for ' + #CurrentFullTableName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '-- ============================================='
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'IF OBJECT_ID(''' + REPLACE(#listSPName,'''','''''') + ''',''P'') IS NOT NULL'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ' DROP PROCEDURE ' + #listSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + ''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'CREATE PROCEDURE ' + #listSPName
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + '' + #ColumnParametersList
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strBegin
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space +' DECLARE #Separator nvarchar(20) =''
WHERE '''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space +' DECLARE #SeparatorAnd nvarchar(20) =''
AND '''
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space +' DECLARE #Statement nvarchar(max) =''SELECT *
FROM ' + REPLACE(#CurrentFullTableName,'''','''''') + '''' + #tableColumnForWhereInList
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' --PRINT #Statement'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' BEGIN TRY'
IF #GenerateDebugScriptForList=1
BEGIN
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' IF 1=0--DEBUG --TODO: verify if not set for final version'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' BEGIN'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' DECLARE #FullQueryForDebug nvarchar(max)=' + #DebugVariablesForList
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' CHAR(13) +CHAR(10) + #Statement'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' '
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' --PRINT #FullQueryForDebug'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' --EXEC [K2FranceDebugDB].dbo.K2FranceDebug ''#FullQueryForDebug DIRECT'', #FullQueryForDebug'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' --EXEC loopbackServerForDebug.[K2FranceDebugDB].dbo.K2FranceDebug ''#FullQueryForDebug loopback'', #FullQueryForDebug'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' END'
END
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' exec sp_executesql #Statement ,N''' + #tableColumnForWhereInListVariables + ''',' + #tableColumnForWhereInListAffectVariables
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' END TRY'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' BEGIN CATCH'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' DECLARE #ErrorToDisplay nvarchar(max)= ''Error trying to execute Query Error number:'' + CAST(ERROR_NUMBER() AS nvarchar(max)) +
--'' Error severity:'' + ISNULL(CAST(ERROR_SEVERITY() AS nvarchar(max)),'''') +
--'' Error state:'' + ISNULL(CAST(ERROR_STATE() AS nvarchar(max)),'''') +
--'' Error procedure:'' + ISNULL(CAST(ERROR_PROCEDURE() AS nvarchar(max)),'''') +
--'' Error line:'' + ISNULL(CAST(ERROR_LINE() AS nvarchar(max)),'''') +
'' Error message:'' + ISNULL(CAST(ERROR_MESSAGE() AS nvarchar(max)),'''')
'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' RAISERROR(#ErrorToDisplay, 16, 1);'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans + ' END CATCH'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + #strEnd
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'EXEC ' + #listSPName + ' ' + #ColumnParametersListForExec
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'GO'
Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + 'SELECT * FROM ' + #CurrentFullTableName + ' ORDER BY 1'
IF #UnCommentExecForDebug = 0 Set #strSPText = #strSPText + CHAR(13) + CHAR(10) + '*/'
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES (#CurrentFullTableName,'List',#strSPText)
Drop table #tmp_Structure
Fetch next from Tables_cursor INTO #CurrentSchemaName,#CurrentTableName
END
CLOSE Tables_cursor
DEALLOCATE Tables_cursor
SET #DropStatement = '
------------------------------------------- TO CLEAN COMPLETELY THE APPLICATION ---------------------------------------
/*' + #DropStatement +'
*/'
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES ('Common','Drop statement to put at the end of final script',#DropStatement)
SELECT * FROM #StatementList
ORDER BY 1
END
GO
--For all tables of schema dbo of database "OlivierDb":
EXEC dbo.GenerateDynamicallyProceduresForTables 'OlivierDB','dbo'
--With all possible parameters:
EXEC dbo.GenerateDynamicallyProceduresForTables #DatabaseName = 'OlivierDB',
#SchemaName = 'dbo',
#TableName = 'Table5',
#NoCount = 1,
#ManageTransaction = 1,
#GenerateDebugScriptForList = 1,
#ParameterForUser = '#UserInP',
#ParameterForCulture = '#CultureInP',
#FirstParametersAreMandatory= 1,
#ProcedureTemplateName = '[{SchemaName}].[{TableName}_Proc_{ActionType}]',
#ColumnNameLimitation = '', --(syscolumns.name LIKE ''%Creation%'' OR syscolumns.name IN (''SomeInt'',''Somebit'') )
#CreationUserMatch = 'syscolumns.name LIKE ''%CreationUser%'' OR syscolumns.name LIKE ''%CreationBy%''',
#CreationDateMatch = 'syscolumns.name LIKE ''%CreationDate%'' OR syscolumns.name LIKE ''%CreatedDate%''',
#ModificationUserMatch = 'syscolumns.name LIKE ''%ModificationUser%'' OR syscolumns.name LIKE ''%ModifiedBy%'' OR syscolumns.name LIKE ''%ModifiedUser%''',
#ModificationDateMatch = 'syscolumns.name LIKE ''%ModificationDate%'' OR syscolumns.name LIKE ''%ModifiedDate%'''
Thanks for the original script.
I improved it with the following :
- Allow to do on another database
- For select, generate dynamically the query according parameters
- Manage columns CreatedBy/Date and ModificationBy/Date
- Work even if special characters are found in schema/table/column
- Allow to add systematically the user and culture.
- Template for procedure name
And lot of options.
Note: code send in two answers as limited to 30000 characters.
IF OBJECT_ID('dbo.GenerateDynamicallyProceduresForTables','P') IS NOT NULL
DROP PROCEDURE dbo.GenerateDynamicallyProceduresForTables
GO
CREATE PROCEDURE dbo.GenerateDynamicallyProceduresForTables #DatabaseName nvarchar(200)=NULL,
#SchemaName nvarchar(200) = NULL,
#TableName nvarchar(200) = NULL,
#NoCount bit=1,
#ManageTransaction bit=1,
#GenerateDebugScriptForList bit = 1,
#ParameterForUser nvarchar(20) = '#UserInP',
#ParameterForCulture nvarchar(20) = '#CultureInP',
#FirstParametersAreMandatory bit=1,
#ProcedureTemplateName nvarchar(100) = '[{SchemaName}].[{TableName}_Proc_{ActionType}]',
#ColumnNameLimitation nvarchar(500)= '', --(syscolumns.name LIKE ''%Creation%'' OR syscolumns.name IN (''SomeInt'',''Somebit'') )
#CreationUserMatch nvarchar(500) = 'syscolumns.name LIKE ''%CreationUser%'' OR syscolumns.name LIKE ''%CreationBy%''',
#CreationDateMatch nvarchar(500) = 'syscolumns.name LIKE ''%CreationDate%'' OR syscolumns.name LIKE ''%CreatedDate%''',
#ModificationUserMatch nvarchar(500) = 'syscolumns.name LIKE ''%ModificationUser%'' OR syscolumns.name LIKE ''%ModifiedBy%'' OR syscolumns.name LIKE ''%ModifiedUser%''',
#ModificationDateMatch nvarchar(500) = 'syscolumns.name LIKE ''%ModificationDate%'' OR syscolumns.name LIKE ''%ModifiedDate%'''
AS
BEGIN
DECLARE #UnCommentExecForDebug bit=0 --To set at 0 for final
DECLARE #StatementList TABLE(id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,FullTableName nvarchar(1000),StatementType nvarchar(100),Statement nvarchar(max))
DECLARE #FirstParameters nvarchar(400)='',#FirstParametersForExec nvarchar(400)=''
IF LEN(#ParameterForUser)>1
BEGIN
SET #FirstParameters = #FirstParameters + #ParameterForUser +' nvarchar(500)' + CASE WHEN #FirstParametersAreMandatory =0 THEN ' = NULL' ELSE '' END + ',
'
SET #FirstParametersForExec = #FirstParametersForExec + #ParameterForUser + CASE WHEN #FirstParametersAreMandatory =0 THEN ' = NULL' ELSE ' =''K2:Denallix\Administrator''' END + ',
'
END
IF LEN(#ParameterForCulture)>1
BEGIN
SET #FirstParameters = #FirstParameters + #ParameterForCulture + ' nvarchar(10)' + CASE WHEN #FirstParametersAreMandatory =0 THEN ' = NULL' ELSE '' END + ',
'
SET #FirstParametersForExec = #FirstParametersForExec + #ParameterForCulture + CASE WHEN #FirstParametersAreMandatory =0 THEN ' = NULL' ELSE '=''en-gb''' END + ',
'
END
IF NOT(LEN(#DatabaseName)>0)
SET #DatabaseName=DB_NAME()
IF LEN(#SchemaName)=0
SET #SchemaName=NULL
IF LEN(#TableName)=0
SET #TableName=NULL
IF NOT(LEN(#ColumnNameLimitation)>0)
SET #ColumnNameLimitation = '1=1'
IF NOT(LEN(#CreationUserMatch)>0)
SET #CreationUserMatch = 'syscolumns.name = ''BIDON12345678917071979'''
IF NOT(LEN(#CreationDateMatch)>0)
SET #CreationDateMatch = 'syscolumns.name = ''BIDON12345678917071979'''
IF NOT(LEN(#ModificationUserMatch)>0)
SET #ModificationUserMatch = 'syscolumns.name = ''BIDON12345678917071979'''
IF NOT(LEN(#ModificationDateMatch)>0)
SET #ModificationDateMatch = 'syscolumns.name = ''BIDON12345678917071979'''
DECLARE #strSpText nVarchar(max) ='USE [' + #DatabaseName + ']'
IF #DatabaseName!=DB_NAME()
INSERT INTO #StatementList (FullTableName,StatementType,Statement) VALUES ('Common','Set current database',#strSPText)
DECLARE #sqlstatementForTables nvarchar(max) = -- Not test with USE [' + #DatabaseName + '] ISSUE ON Table iDENTITY.Identity: 'Could not complete cursor operation because the set options have changed since the cursor was declared
N'
DECLARE Tables_cursor CURSOR FOR
SELECT TABLE_SCHEMA,TABLE_NAME
FROM [' + #DatabaseName + '].INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE=''BASE TABLE''
AND (TABLE_SCHEMA=#pSchemaName OR #pSchemaName IS NULL)
AND (Table_Name=#pTableName OR #pTableName IS NULL)'
--EXEC loopbackServerForDebug.[K2FranceDebugDB].dbo.K2FranceDebug '#sqlstatementForColumns',#sqlstatementForColumns
exec sp_executesql #sqlstatementForTables, N'#pSchemaName nvarchar(200),#pTableName nvarchar(200)', #pSchemaName=#SchemaName, #pTableName=#TableName;
OPEN Tables_cursor
DECLARE #CurrentSchemaName nvarchar(100),#CurrentFullTableName nvarchar(1000),#CurrentTableName nVarchar(1000),
#DropStatement nvarchar(max)=''
Fetch next
from Tables_cursor
INTO #CurrentSchemaName,#CurrentTableName
WHILE ##FETCH_STATUS=0
BEGIN
SET #CurrentFullTableName='['+#CurrentSchemaName+'].['+#CurrentTableName+']';
--PRINT #CurrentFullTableName
Declare #dbName nVarchar(50)
Declare #insertSPName nVarchar(4000), #updateSPName nVarchar(4000), #deleteSPName nVarchar(4000), #listSPName nVarchar(4000)--, #ReadSPName nVarchar(50) ;
Declare #ColumnParametersInsert nVarchar(max), #ColumnDefForInsert nVarchar(max),#ColumnInValueForInsert nVarchar(max),
#ColumnParametersList nVarchar(max),#ColumnParametersListForExec nVarchar(max),
#tableColumnForWhereInList nvarchar(max),
#tableColumnForWhereInListVariables nVarchar(max), #tableColumnForWhereInListAffectVariables nVarchar(max),#DebugVariablesForList nvarchar(max)='',
#ColumnParametersInsertForExec nvarchar(max)
Declare #tableCols nVarchar(max), #ColumnParametersUpdate nVarchar(max),#ColumnParametersUpdateForExec nVarchar(max);
Declare #space nVarchar(50) = REPLICATE(' ', 4) ;
Declare #colName nVarchar(max) ;
Declare #DataType nvarchar(200),#colVariable nVarchar(200),#colVariableProc nVarchar(200);
Declare #colParameter nVarchar(max) ;
Declare #colAllowNull nvarchar(15), #colIsPrimaryKey INT,#ColIsIdentityAutoIncrement INT,#ColLength INT,#ColIsComputed INT,#ColMatchCreationUser INT,#ColMatchCreationDate INT,#ColMatchModificationUser INT,#ColMatchModificationDate INT;
Declare #updCols nVarchar(max);
Declare #ColumnParametersDelete nVarchar(max),#ColumnParametersDeleteForExec nVarchar(max),
#LastPrimaryKey nvarchar(max),#NbPrimaryKey INT=0,#ColNumber int=0
Declare #whereCols nVarchar(2000);
DECLARE #SetVariablesForExec nvarchar(max)='',#SetVariablesForExecUpdate nvarchar(max)='', #SetVariablesForExecDelete nvarchar(max)=''
DECLARE #strBegin nvarchar(1000)=' AS' + CHAR(13) + CHAR(10) + 'BEGIN',#spaceForTrans nvarchar(10)=''
IF #NoCount=1
Set #strBegin = #strBegin + CHAR(13) + CHAR(10) + #space + 'SET NOCOUNT ON '
IF #ManageTransaction = 1
BEGIN
Set #strBegin = #strBegin + CHAR(13) + CHAR(10) + #space + 'SET XACT_ABORT ON -- if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.'
Set #strBegin = #strBegin + CHAR(13) + CHAR(10) + ''
Set #strBegin = #strBegin + CHAR(13) + CHAR(10) + #space + 'BEGIN TRAN '
SET #spaceForTrans= #space;
END
DECLARE #strEnd nvarchar(1000)=''
IF #ManageTransaction = 1
Set #strEnd = #strEnd + CHAR(13) + CHAR(10) + #space + 'COMMIT TRAN '
SET #strEnd = #strEnd + CHAR(13) + CHAR(10) + 'END'
Set #strEnd = #strEnd + CHAR(13) + CHAR(10) + 'GO'
Set #strEnd = #strEnd + CHAR(13) + CHAR(10) + ''
IF #UnCommentExecForDebug = 0 Set #strEnd = #strEnd + CHAR(13) + CHAR(10) + '/*'
IF #ProcedureTemplateName IS NULL
BEGIN
Set #insertSPName = '['+#CurrentSchemaName+'].[sp_' + #CurrentTableName +'_insert]' ;
Set #updateSPName = '['+#CurrentSchemaName+'].[sp_' + #CurrentTableName +'_update]' ;
Set #deleteSPName = '['+#CurrentSchemaName+'].[sp_' + #CurrentTableName +'_delete]' ;
set #listSPName = '['+#CurrentSchemaName+'].[sp_' + #CurrentTableName +'_list]' ;
END
ELSE
BEGIN
DECLARE #ProcedureName nvarchar(200)=REPLACE(REPLACE(#ProcedureTemplateName,'{SchemaName}',ISNULL(#SchemaName,#CurrentSchemaName)),'{TableName}',ISNULL(#TableName,#CurrentTableName));
Set #insertSPName = REPLACE(#ProcedureName,'{ActionType}','Insert')
Set #updateSPName = REPLACE(#ProcedureName,'{ActionType}','Update')
Set #deleteSPName = REPLACE(#ProcedureName,'{ActionType}','Delete')
Set #listSPName = REPLACE(#ProcedureName,'{ActionType}','List')
END
SET #DropStatement = #DropStatement+ '
DROP PROCEDURE ' + #insertSPName + '
DROP PROCEDURE ' + #updateSPName + '
DROP PROCEDURE ' + #deleteSPName +'
DROP PROCEDURE ' + #listSPName
Set #ColumnParametersInsert = #FirstParameters ;
SET #ColumnParametersInsertForExec = #FirstParametersForExec
Set #ColumnParametersUpdate=#FirstParameters
SET #ColumnParametersUpdateForExec=#FirstParametersForExec
Set #ColumnParametersDelete = #FirstParameters ;
SET #ColumnParametersDeleteForExec = #FirstParametersForExec ;
SET #ColumnParametersList = #FirstParameters;
SET #ColumnParametersListForExec = #FirstParametersForExec
SET #tableColumnForWhereInList= ''
SET #tableColumnForWhereInListVariables =''
SET #tableColumnForWhereInListAffectVariables =''
SET #DebugVariablesForList ='';
Set #ColumnDefForInsert = '' ;
Set #ColumnInValueForInsert = '' ;
Set #strSPText = '' ;
Set #tableCols = '' ;
Set #updCols = '' ;
Set #whereCols = '' ;
SET NOCOUNT ON
CREATE TABLE #tmp_Structure (colid int,ColumnName nvarchar(max),
ColumnVariable nvarchar(max),
DataType nvarchar(max),
ColumnParameter nvarchar(max),
AllowNull int,
IsPrimaryKey int,
IsIdentityAutoIncrement int,
ColLength int,
IsIsComputedColumn int,
ColMatchCreationUser int,ColMatchCreationDate int,
ColMatchModificationUser INT,ColMatchModificationDate INT)
DECLARE #sqlstatementForColumns nvarchar(max) =
N'USE [' + #DatabaseName + ']
SELECT distinct
--sysobjects.name as ''Table'',
syscolumns.colid ,
''['' + syscolumns.name + '']'' as ''ColumnName'',
''#''+syscolumns.name as ''ColumnVariable'',
systypes.name +
Case When systypes.xusertype in (165,167,175,231,239 ) Then ''('' + Convert(varchar(10),Case When syscolumns.length=-1 Then ''max'' else CAST(syscolumns.length AS nvarchar(10)) end) +'')'' Else '''' end as ''DataType'' ,
systypes.name + Case When systypes.xusertype in (165,167,175,231,239 ) Then ''('' + Convert(varchar(10),Case When syscolumns.length=-1 Then ''max'' else CAST(syscolumns.length AS nvarchar(10)) end) +'')'' Else '''' end as ''ColumnParameter'',
COLUMNPROPERTY(OBJECT_ID(#pFullTableName),syscolumns.name,''AllowsNull'') AS AllowNull,
(SELECT COUNT(*)
FROM [' + #DatabaseName + '].INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
[' + #DatabaseName + '].INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type = ''PRIMARY KEY''
AND Col.Table_Name = #pTableName
AND Tab.TABLE_SCHEMA=#pSchemaName
AND Col.Column_Name = syscolumns.name
) AS IsPrimaryKey,
SC.is_identity AS IsIdentityAutoIncrement,
syscolumns.length,
(SELECT COUNT(*)
FROM sys.computed_columns
WHERE computed_columns.object_id=sysobjects.id
AND computed_columns.Name=syscolumns.name) AS IsComputedColumn,
CASE WHEN ' + #CreationUserMatch +' THEN 1 ELSE 0 END AS ColMatchCreationUser,
CASE WHEN ' + #CreationDateMatch +' THEN 1 ELSE 0 END AS ColMatchCreationDate,
CASE WHEN ' + #ModificationUserMatch +' THEN 1 ELSE 0 END AS ColMatchModificationUser,
CASE WHEN ' + #ModificationDateMatch +' THEN 1 ELSE 0 END AS ColMatchModificationDate
FROM sysobjects
LEFT JOIN syscolumns ON syscolumns.id=sysobjects.id
LEFT JOIN systypes ON systypes.xusertype=syscolumns.xusertype
LEFT JOIN sys.columns SC ON SC.object_id = sysobjects.id
AND SC.name=syscolumns.name
Where sysobjects.xtype = ''u''
and sysobjects.id = OBJECT_ID(#pFullTableName)
AND (' + #ColumnNameLimitation + ')
Order by syscolumns.colid'
--PRINT #sqlstatementForColumns
--EXEC loopbackServerForDebug.[K2FranceDebugDB].dbo.K2FranceDebug '#sqlstatementForColumns',#sqlstatementForColumns
INSERT INTO #tmp_Structure
exec sp_executesql #sqlstatementForColumns, N'#pSchemaName nvarchar(200),#pTableName nvarchar(200),#pFullTableName nvarchar(1000)', #pSchemaName=#CurrentSchemaName, #pTableName=#CurrentTableName,#pFullTableName=#CurrentFullTableName;
--SELECT * FROM #tmp_Structure
/* Read the table structure and populate variables*/
DECLARE SpText_Cursor CURSOR FOR
SELECT ColumnName, ColumnVariable, DataType, ColumnParameter, AllowNull, IsPrimaryKey, IsIdentityAutoIncrement,ColLength, IsIsComputedColumn,ColMatchCreationUser,ColMatchCreationDate,ColMatchModificationUser,ColMatchModificationDate
FROM #tmp_Structure
OPEN SpText_Cursor
FETCH NEXT FROM SpText_Cursor INTO #colName, #colVariable, #DataType, #colParameter, #colAllowNull,#colIsPrimaryKey, #ColIsIdentityAutoIncrement,#ColLength, #ColIsComputed,#ColMatchCreationUser,#ColMatchCreationDate,#ColMatchModificationUser,#ColMatchModificationDate
WHILE ##FETCH_STATUS = 0
BEGIN
SET #ColNumber=#ColNumber+1
SET #SetVariablesForExec = #SetVariablesForExec + CASE WHEN #colAllowNull =1 THEN ''
ELSE CASE WHEN #DataType IN ('datetime','datetime2','smalldatetime','date') AND #SetVariablesForExec NOT LIKE '%#Date%' THEN CHAR(13) +CHAR(10) + 'DECLARE #Date datetime =GetDate()'
WHEN #DataType IN ('uniqueidentifier') AND #SetVariablesForExec NOT LIKE '%#GuidTest%' THEN CHAR(13) +CHAR(10) + 'DECLARE #TheGuid uniqueidentifier =NEWID()'
ELSE ''
END
END
--RegEx to keep only alphanumeric characters:
DECLARE #MatchExpression nvarchar(20) = '%[^a-z0-9]%',#DateTypeWithoutSpecialCharacters nvarchar(100)=#DataType;
WHILE PatIndex(#MatchExpression, #DateTypeWithoutSpecialCharacters) > 0
SET #DateTypeWithoutSpecialCharacters = Stuff(#DateTypeWithoutSpecialCharacters, PatIndex(#MatchExpression, #DateTypeWithoutSpecialCharacters), 1, '')
--Remove Special characters (like space...) for variable name
WHILE PatIndex(#MatchExpression, #colVariable) > 0
SET #colVariable = Stuff(#colVariable, PatIndex(#MatchExpression, #colVariable), 1, '')
SET #colVariableProc = '#p'+ #colVariable
SET #colVariable = '#'+ #colVariable
SET #colParameter = #colVariable + ' ' + #colParameter
DECLARE #AffectationForExec nvarchar(max)=#colVariable + CASE WHEN #colAllowNull =1 THEN ' = NULL'
ELSE ' = ' + CASE WHEN #DataType IN ('Text','sysname') OR #DataType LIKE '%char%' THEN '''' + SUBSTRING ( CAST(ABS(#ColLength) AS nvarchar(10)) + 'TEST' + #DateTypeWithoutSpecialCharacters,0,CASE WHEN #ColLength < 0 THEN 1000 WHEN #DataType LIKE 'nchar%' THEN #ColLength/2+1 ELSE #ColLength END) + ''''
WHEN #DataType IN ('int','numeric','bigint','tinyint') THEN CAST(#ColNumber AS nvarchar(10))
WHEN #DataType IN ('bit') THEN '0'
WHEN #DataType IN ('float') THEN CAST(#ColNumber AS nvarchar(10)) + '.' + CAST(#ColNumber+1 AS nvarchar(10))
WHEN #DataType IN ('datetime','datetime2','smalldatetime','date') THEN '#Date'
WHEN #DataType IN ('uniqueidentifier') THEN '#TheGuid'
WHEN #DataType IN ('xml') THEN '''<testXML><value name="test">' + CAST(#ColNumber AS nvarchar(10)) + '</value></testXML>'''
ELSE '''1''--Currently Not managed'
END
END + ', --Type ' + #DataType + CHAR(13) + CHAR(10) + #space
IF #ColIsIdentityAutoIncrement = 0 AND #ColIsComputed = 0
BEGIN
IF #ColMatchModificationUser = 0 AND #ColMatchModificationDate = 0
Set #ColumnDefForInsert = #ColumnDefForInsert + #colName+ ',' + CHAR(13) + CHAR(10) + #space + #space + #spaceForTrans ;
IF #ColMatchCreationUser= 0 AND #ColMatchCreationDate = 0 AND #ColMatchModificationUser = 0 AND #ColMatchModificationDate = 0
BEGIN
Set #ColumnParametersInsert = #ColumnParametersInsert + #colParameter + CASE WHEN #colAllowNull =1 THEN ' = NULL' ELSE '' END + ',' + CHAR(13) + CHAR(10) + #space ;
SET #ColumnParametersInsertForExec = #ColumnParametersInsertForExec + #AffectationForExec
END
IF #ColMatchCreationUser= 1
BEGIN
IF LEN(#ParameterForUser)>1
Set #ColumnInValueForInsert = #ColumnInValueForInsert + 'ISNULL(' + #ParameterForUser + ',SYSTEM_USER)'
ELSE
Set #ColumnInValueForInsert = #ColumnInValueForInsert + 'SYSTEM_USER'
END
ELSE
BEGIN
IF #ColMatchCreationDate= 1
Set #ColumnInValueForInsert = #ColumnInValueForInsert + 'GETDATE()'
ELSE
IF #ColMatchModificationUser = 0 AND #ColMatchModificationDate = 0
Set #ColumnInValueForInsert = #ColumnInValueForInsert + #colVariable
END
IF #ColMatchCreationUser= 1 OR #ColMatchCreationDate= 1 OR #ColMatchModificationUser = 0 AND #ColMatchModificationDate = 0
SET #ColumnInValueForInsert =#ColumnInValueForInsert + ',' + CHAR(13) + CHAR(10) + #space + #space+ #spaceForTrans
Set #tableCols = #tableCols + #colName + ',' ;
IF #ColMatchModificationUser = 1
BEGIN
IF LEN(#ParameterForUser)>1
Set #updCols = #updCols + #colName + ' = ISNULL(' + #ParameterForUser + ',SYSTEM_USER)';
ELSE
Set #updCols = #updCols + #colName + ' = SYSTEM_USER';
END
ELSE
BEGIN
IF #ColMatchModificationDate = 1
Set #updCols = #updCols + #colName + ' = GETDATE()';
ELSE
IF #ColMatchCreationUser=0 AND #ColMatchCreationDate=0
Set #updCols = #updCols + #colName + ' = ' + #colVariable;
END
IF #ColMatchModificationUser = 1 OR #ColMatchModificationDate = 1 OR #ColMatchCreationUser=0 AND #ColMatchCreationDate=0
SET #updCols =#updCols + ',' + CHAR(13) + CHAR(10) + #space + #space+ ' ' + #spaceForTrans
END
SET #ColumnParametersList = #ColumnParametersList + #colParameter + ' = NULL' + ',' + CHAR(13) + CHAR(10) + #space ;
SET #ColumnParametersListForExec = #ColumnParametersListForExec+ #colVariable + ' = NULL, --Type ' + #DataType + CHAR(13) + CHAR(10) + #space
IF #ColIsIdentityAutoIncrement = 1 AND #DataType='int'
BEGIN
SET #SetVariablesForExecUpdate = CHAR(13)+CHAR(10)+'DECLARE #PrimaryKeyValue INT= (SELECT MIN(' + #colName + ') FROM ' + #CurrentFullTableName + ')'
SET #AffectationForExec = #colVariable + '= #PrimaryKeyValue, --Type ' + #DataType + CHAR(13) + CHAR(10) + #space
END
IF #ColIsComputed = 0 AND #ColMatchCreationUser=0 AND #ColMatchCreationDate=0 AND #ColMatchModificationUser=0 AND #ColMatchModificationDate=0
BEGIN
Set #ColumnParametersUpdate = #ColumnParametersUpdate + #colParameter + ',' + CHAR(13) + CHAR(10) + #space ;
SET #ColumnParametersUpdateForExec = #ColumnParametersUpdateForExec + #AffectationForExec
END
IF #DataType NOT IN ('text')
BEGIN
IF #DataType NOT IN ('Xml')
BEGIN
SET #tableColumnForWhereInList = #tableColumnForWhereInList + '
IF ' + #colVariable + ' IS NOT NULL
BEGIN
SET #Statement= #Statement+ #Separator + ''' + REPLACE(#colName,'''','''''') + '= '+ #colVariableProc +'''
SET #Separator = #SeparatorAnd
END'
SET #tableColumnForWhereInListVariables = #tableColumnForWhereInListVariables + #space + #space + #space + #spaceForTrans + #colVariableProc + ' ' + #DataType +',
'
SET #tableColumnForWhereInListAffectVariables = #tableColumnForWhereInListAffectVariables + #space + #space + #space + #spaceForTrans + #colVariableProc + '=' + #colVariable + ',
'
END
SET #DebugVariablesForList = #DebugVariablesForList+ CHAR(13) +CHAR(10) + #space + #space + #space + #space +#space+ #spaceForTrans
IF #DataType IN ('Xml')
SET #DebugVariablesForList = #DebugVariablesForList+ 'ISNULL(''DECLARE '+ #colVariableProc + ' ' + #DataType+' = CAST('''''' + REPLACE(CAST(' +#colVariable + ' as nvarchar(max)),'''''''','''''''''''') + ''''''AS XML);''+CHAR(13)+CHAR(10) ,'''') + '
ELSE
SET #DebugVariablesForList = #DebugVariablesForList+ 'ISNULL(''DECLARE '+ #colVariableProc + ' ' + #DataType+' = '''''' + REPLACE(' +#colVariable + ','''''''','''''''''''') + '''''';''+CHAR(13)+CHAR(10) ,'''') + '
END
IF #colIsPrimaryKey= 1
BEGIN
IF #ColIsIdentityAutoIncrement = 1 AND #DataType='int'
BEGIN
SET #SetVariablesForExecDelete = CHAR(13)+CHAR(10)+'DECLARE #PrimaryKeyValue INT= (SELECT MAX(' + #colName + ') FROM ' + #CurrentFullTableName + ')'
END
SET #ColumnParametersDelete = #ColumnParametersDelete + #colParameter +', ' + CHAR(13) + CHAR(10) + #space ;
SET #ColumnParametersDeleteForExec = #ColumnParametersDeleteForExec + #AffectationForExec
SET #whereCols = #whereCols + #colName + ' = ' + #colVariable + ' AND ' ;
SET #NbPrimaryKey = #NbPrimaryKey +1
SET #LastPrimaryKey = #colName
END
FETCH NEXT FROM SpText_Cursor INTO #colName, #colVariable, #DataType,#colParameter, #colAllowNull,#colIsPrimaryKey,#ColIsIdentityAutoIncrement,#ColLength,#ColIsComputed,#ColMatchCreationUser,#ColMatchCreationDate,#ColMatchModificationUser,#ColMatchModificationDate
END
CLOSE SpText_Cursor
DEALLOCATE SpText_Cursor
IF #ColumnDefForInsert IS NULL
RAISERROR('#ColumnDefForInsert IS NULL',16,1)
IF #ColumnParametersInsert IS NULL
RAISERROR('#ColumnParametersInsert IS NULL',16,1)
IF #ColumnParametersInsertForExec IS NULL
RAISERROR('#ColumnParametersInsertForExec IS NULL',16,1)
IF #ColumnInValueForInsert IS NULL
RAISERROR('#ColumnInValueForInsert IS NULL',16,1)
IF #tableCols IS NULL
RAISERROR('#tableCols IS NULL',16,1)
IF #updCols IS NULL
RAISERROR('#updCols IS NULL',16,1)
IF #ColumnParametersDelete IS NULL
RAISERROR('#ColumnParametersDelete IS NULL',16,1)
IF #whereCols IS NULL
RAISERROR('#whereCols IS NULL',16,1)
DECLARE #LastPosOfComma INT
If (LEN(#ColumnParametersUpdate)>0)
BEGIN
Set #ColumnParametersUpdate = LEFT(#ColumnParametersUpdate,LEN(#ColumnParametersUpdate)-3) ;
SET #LastPosOfComma = LEN(#ColumnParametersUpdateForExec) - CHARINDEX(' ,',REVERSE(#ColumnParametersUpdateForExec))
SET #ColumnParametersUpdateForExec = LEFT(#ColumnParametersUpdateForExec,#LastPosOfComma+3) + SUBSTRING(#ColumnParametersUpdateForExec,#LastPosOfComma+5,40000);
END
--See next post for the end of procedure