MS SQL server "Generate script" with insert values in a single command - sql-server

When using "Generate Script" feature in MS SQL Management Studio we get data exported as well, but all values are inserted in a separate steps, which looks something like
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (3, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 30 %', NULL, 13, 0)
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (4, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 40 %', NULL, 14, 0)
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (5, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 50 %', NULL, 15, 0)
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (6, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 60 %', NULL, 16, 0)
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (7, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 70 %', NULL, 17, 0)
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted]) VALUES (8, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 80 %', NULL, 18, 0)
Is there any way to make this script generation and forcing SSMS to create insert queries in a single or several larger steps, like:
INSERT [dbo].[table] ([table_id], [table_version], [table_timestamp], [table_user], [table_percent], [table_hid], [table_latestversionid], [table_isdeleted])
VALUES
(3, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 30 %', NULL, 13, 0),
(4, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 40 %', NULL, 14, 0),
(5, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 50 %', NULL, 15, 0),
(6, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 60 %', NULL, 16, 0),
(7, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 70 %', NULL, 17, 0),
(8, -1, CAST(N'2015-06-04 13:03:38.000' AS DateTime), N'init', N' 80 %', NULL, 18, 0);
Thanks

--First Create The SP GenerateInsert The Run The Below Mention CODE Which will give the Desire Output..
IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.GenerateInsert') AND type in (N'P', N'PC'))
DROP PROCEDURE dbo.GenerateInsert;
GO
CREATE PROCEDURE dbo.GenerateInsert
(
#ObjectName nvarchar(261)
, #TargetObjectName nvarchar(261) = NULL
, #OmmitInsertColumnList bit = 0
, #GenerateSingleInsertPerRow bit = 0
, #UseSelectSyntax bit = 0
, #UseColumnAliasInSelect bit = 0
, #FormatCode bit = 1
, #GenerateOneColumnPerLine bit = 0
, #GenerateGo bit = 0
, #PrintGeneratedCode bit = 1
, #TopExpression nvarchar(max) = NULL
, #FunctionParameters nvarchar(max) = NULL
, #SearchCondition nvarchar(max) = NULL
, #OrderByExpression nvarchar(max) = NULL
, #OmmitUnsupportedDataTypes bit = 1
, #PopulateIdentityColumn bit = 0
, #PopulateTimestampColumn bit = 0
, #PopulateComputedColumn bit = 0
, #GenerateProjectInfo bit = 1
, #GenerateSetNoCount bit = 1
, #GenerateStatementTerminator bit = 1
, #ShowWarnings bit = 1
, #Debug bit = 0
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CrLf char(2)
SET #CrLf = CHAR(13) + CHAR(10);
DECLARE #ColumnName sysname;
DECLARE #DataType sysname;
DECLARE #ColumnList nvarchar(max);
SET #ColumnList = N'';
DECLARE #SelectList nvarchar(max);
SET #SelectList = N'';
DECLARE #SelectStatement nvarchar(max);
SET #SelectStatement = N'';
DECLARE #OmittedColumnList nvarchar(max);
SET #OmittedColumnList = N'';
DECLARE #InsertSql nvarchar(max);
SET #InsertSql = N'INSERT INTO ' + COALESCE(#TargetObjectName,#ObjectName);
DECLARE #ValuesSql nvarchar(max);
SET #ValuesSql = N'VALUES (';
DECLARE #SelectSql nvarchar(max);
SET #SelectSql = N'SELECT ';
DECLARE #TableData table (TableRow nvarchar(max));
DECLARE #Results table (TableRow nvarchar(max));
DECLARE #TableRow nvarchar(max);
DECLARE #RowNo int;
IF PARSENAME(#ObjectName,3) IS NOT NULL
OR PARSENAME(#ObjectName,4) IS NOT NULL
BEGIN
RAISERROR(N'Server and database names are not allowed to specify in #ObjectName parameter. Required format is [schema_name.]object_name',16,1);
RETURN -1;
END
IF OBJECT_ID(#ObjectName,N'U') IS NULL -- USER_TABLE
AND OBJECT_ID(#ObjectName,N'V') IS NULL -- VIEW
AND OBJECT_ID(#ObjectName,N'IF') IS NULL -- SQL_INLINE_TABLE_VALUED_FUNCTION
AND OBJECT_ID(#ObjectName,N'TF') IS NULL -- SQL_TABLE_VALUED_FUNCTION
BEGIN
RAISERROR(N'User table, view, table-valued or inline function %s not found or insuficient permission to query the provided object.',16,1,#ObjectName);
RETURN -1;
END
IF NOT EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE IN ('BASE TABLE','VIEW')
AND TABLE_NAME = PARSENAME(#ObjectName,1)
AND (TABLE_SCHEMA = PARSENAME(#ObjectName,2)
OR PARSENAME(#ObjectName,2) IS NULL)
) AND NOT EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE IN ('FUNCTION')
AND DATA_TYPE = 'TABLE'
AND SPECIFIC_NAME = PARSENAME(#ObjectName,1)
AND (SPECIFIC_SCHEMA = PARSENAME(#ObjectName,2)
OR PARSENAME(#ObjectName,2) IS NULL)
)
BEGIN
RAISERROR(N'User table, view, table-valued or inline function %s not found or insuficient permission to query the provided object.',16,1,#ObjectName);
RETURN -1;
END
DECLARE ColumnCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT c.name ColumnName
,COALESCE(TYPE_NAME(c.system_type_id),t.name) DataType
FROM sys.objects o
INNER JOIN sys.columns c ON c.object_id = o.object_id
LEFT JOIN sys.types t ON t.system_type_id = c.system_type_id
AND t.user_type_id = c.user_type_id
WHERE o.type IN (N'U',N'V',N'IF',N'TF')
-- U = USER_TABLE
-- V = VIEW
-- IF = SQL_INLINE_TABLE_VALUED_FUNCTION
-- TF = SQL_TABLE_VALUED_FUNCTION
AND (o.object_id = OBJECT_ID(#ObjectName)
OR o.name = #ObjectName)
AND (COLUMNPROPERTY(c.object_id,c.name,'IsIdentity') != 1
OR #PopulateIdentityColumn = 1)
AND (COLUMNPROPERTY(c.object_id,c.name,'IsComputed') != 1
OR #PopulateComputedColumn = 1)
ORDER BY COLUMNPROPERTY(c.object_id,c.name,'ordinal') -- ORDINAL_POSITION
FOR READ ONLY
;
OPEN ColumnCursor;
FETCH NEXT FROM ColumnCursor INTO #ColumnName,#DataType;
WHILE ##FETCH_STATUS = 0
BEGIN
-- Handle different data types
DECLARE #ColumnExpression nvarchar(max);
SET #ColumnExpression =
CASE
WHEN #DataType IN ('char','varchar','text','uniqueidentifier')
THEN N'ISNULL(''''''''+REPLACE(CONVERT(varchar(max),'+ QUOTENAME(#ColumnName) + N'),'''''''','''''''''''')+'''''''',''NULL'') COLLATE database_default'
WHEN #DataType IN ('nchar','nvarchar','sysname','ntext','sql_variant','xml')
THEN N'ISNULL(''N''''''+REPLACE(CONVERT(nvarchar(max),'+ QUOTENAME(#ColumnName) + N'),'''''''','''''''''''')+'''''''',''NULL'') COLLATE database_default'
WHEN #DataType IN ('int','bigint','smallint','tinyint','decimal','numeric','bit')
THEN N'ISNULL(CONVERT(varchar(max),'+ QUOTENAME(#ColumnName) + N'),''NULL'') COLLATE database_default'
WHEN #DataType IN ('float','real','money','smallmoney')
THEN N'ISNULL(CONVERT(varchar(max),'+ QUOTENAME(#ColumnName) + N',2),''NULL'') COLLATE database_default'
WHEN #DataType IN ('datetime','smalldatetime','date','time','datetime2','datetimeoffset')
THEN N'''CONVERT('+#DataType+',''+ISNULL(''''''''+CONVERT(varchar(max),'+ QUOTENAME(#ColumnName) + N',121)+'''''''',''NULL'') COLLATE database_default' + '+'',121)'''
WHEN #DataType IN ('rowversion','timestamp')
THEN
CASE WHEN #PopulateTimestampColumn = 1
THEN N'''CONVERT(varbinary(max),''+ISNULL(''''''''+CONVERT(varchar(max),CONVERT(varbinary(max),'+ QUOTENAME(#ColumnName) + N'),1)+'''''''',''NULL'') COLLATE database_default' + '+'',1)'''
ELSE N'''NULL''' END
WHEN #DataType IN ('binary','varbinary','image')
THEN N'''CONVERT(varbinary(max),''+ISNULL(''''''''+CONVERT(varchar(max),CONVERT(varbinary(max),'+ QUOTENAME(#ColumnName) + N'),1)+'''''''',''NULL'') COLLATE database_default' + '+'',1)'''
WHEN #DataType IN ('geography')
-- convert geography to text: ?? column.STAsText();
-- convert text to geography: ?? geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326);
THEN NULL
ELSE NULL END;
IF #ColumnExpression IS NULL
AND #OmmitUnsupportedDataTypes != 1
BEGIN
RAISERROR(N'Datatype %s is not supported. Use #OmmitUnsupportedDataTypes to exclude unsupported columns.',16,1,#DataType);
RETURN -1;
END
IF #ColumnExpression IS NULL
BEGIN
SET #OmittedColumnList = #OmittedColumnList
+ CASE WHEN #OmittedColumnList != N'' THEN N'; ' ELSE N'' END
+ N'column ' + QUOTENAME(#ColumnName)
+ N', datatype ' + #DataType;
END
IF #ColumnExpression IS NOT NULL
BEGIN
SET #ColumnList = #ColumnList
+ CASE WHEN #ColumnList != N'' THEN N',' ELSE N'' END
+ QUOTENAME(#ColumnName)
+ CASE WHEN #GenerateOneColumnPerLine = 1 THEN #CrLf ELSE N'' END;
SET #SelectList = #SelectList
+ CASE WHEN #SelectList != N'' THEN N'+'',''+' + #CrLf ELSE N'' END
+ #ColumnExpression
+ CASE WHEN #UseColumnAliasInSelect = 1 AND #UseSelectSyntax = 1 THEN N'+'' ' + QUOTENAME(#ColumnName) + N'''' ELSE N'' END
+ CASE WHEN #GenerateOneColumnPerLine = 1 THEN N'+CHAR(13)+CHAR(10)' ELSE N'' END;
END
FETCH NEXT FROM ColumnCursor INTO #ColumnName,#DataType;
END
CLOSE ColumnCursor;
DEALLOCATE ColumnCursor;
IF NULLIF(#ColumnList,N'') IS NULL
BEGIN
RAISERROR(N'No columns to select.',16,1);
RETURN -1;
END
IF #Debug = 1
BEGIN
PRINT(N'--Column list');
PRINT(#ColumnList);
END
IF NULLIF(#OmittedColumnList,'') IS NOT NULL
AND #ShowWarnings = 1
BEGIN
PRINT(N'--*************************');
PRINT(N'--WARNING: The following columns have been omitted because of unsupported datatypes: ' + #OmittedColumnList);
PRINT(N'--*************************');
END
IF #GenerateSingleInsertPerRow = 1
BEGIN
SET #SelectList =
N'''' + #InsertSql + N'''+' + #CrLf
+ CASE WHEN #FormatCode = 1
THEN N'CHAR(13)+CHAR(10)+' + #CrLf
ELSE N''' ''+'
END
+ CASE WHEN #OmmitInsertColumnList = 1
THEN N''
ELSE N'''(' + #ColumnList + N')''+' + #CrLf
END
+ CASE WHEN #FormatCode = 1
THEN N'CHAR(13)+CHAR(10)+' + #CrLf
ELSE N''' ''+'
END
+ CASE WHEN #UseSelectSyntax = 1
THEN N'''' + #SelectSql + N'''+'
ELSE N'''' + #ValuesSql + N'''+'
END
+ #CrLf
+ #SelectList
+ CASE WHEN #UseSelectSyntax = 1
THEN N''
ELSE N'+' + #CrLf + N''')'''
END
+ CASE WHEN #GenerateStatementTerminator = 1
THEN N'+'';'''
ELSE N''
END
+ CASE WHEN #GenerateGo = 1
THEN N'+' + #CrLf + N'CHAR(13)+CHAR(10)+' + #CrLf + N'''GO'''
ELSE N''
END
;
END ELSE BEGIN
SET #SelectList =
CASE WHEN #UseSelectSyntax = 1
THEN N'''' + #SelectSql + N'''+'
ELSE N'''(''+'
END
+ #CrLf
+ #SelectList
+ CASE WHEN #UseSelectSyntax = 1
THEN N''
ELSE N'+' + #CrLf + N''')'''
END
;
END
SET #SelectStatement = N'SELECT'
+ CASE WHEN NULLIF(#TopExpression,N'') IS NOT NULL
THEN N' TOP ' + #TopExpression
ELSE N'' END
+ #CrLf + #SelectList + #CrLf
+ N'FROM ' + #ObjectName
+ CASE WHEN NULLIF(#FunctionParameters,N'') IS NOT NULL
THEN #FunctionParameters
ELSE N'' END
+ CASE WHEN NULLIF(#SearchCondition,N'') IS NOT NULL
THEN #CrLf + N'WHERE ' + #SearchCondition
ELSE N'' END
+ CASE WHEN NULLIF(#OrderByExpression,N'') IS NOT NULL
THEN #CrLf + N'ORDER BY ' + #OrderByExpression
ELSE N'' END
+ #CrLf + N';' + #CrLf + #CrLf
;
IF #Debug = 1
BEGIN
PRINT(#CrLf + N'--Select statement');
PRINT(#SelectStatement);
END
INSERT INTO #TableData
EXECUTE (#SelectStatement);
IF #GenerateProjectInfo = 1
BEGIN
INSERT INTO #Results
SELECT N'--INSERTs generated by GenerateInsert (Build 6)'
UNION SELECT N''
END
IF #GenerateSetNoCount = 1
BEGIN
INSERT INTO #Results
SELECT N'SET NOCOUNT ON'
END
IF #PopulateIdentityColumn = 1
BEGIN
INSERT INTO #Results
SELECT N'SET IDENTITY_INSERT ' + COALESCE(#TargetObjectName,#ObjectName) + N' ON'
END
IF #GenerateSingleInsertPerRow = 1
BEGIN
INSERT INTO #Results
SELECT TableRow
FROM #TableData
END ELSE BEGIN
IF #FormatCode = 1
BEGIN
INSERT INTO #Results
SELECT #InsertSql;
IF #OmmitInsertColumnList != 1
BEGIN
INSERT INTO #Results
SELECT N'(' + #ColumnList + N')';
END
IF #UseSelectSyntax != 1
BEGIN
INSERT INTO #Results
SELECT N'VALUES';
END
END ELSE BEGIN
INSERT INTO #Results
SELECT #InsertSql
+ CASE WHEN #OmmitInsertColumnList = 1 THEN N'' ELSE N' (' + #ColumnList + N')' END
+ CASE WHEN #UseSelectSyntax = 1 THEN N'' ELSE N' VALUES' END
END
SET #RowNo = 0;
DECLARE DataCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT TableRow
FROM #TableData
FOR READ ONLY
;
OPEN DataCursor;
FETCH NEXT FROM DataCursor INTO #TableRow;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #RowNo = #RowNo + 1;
INSERT INTO #Results
SELECT
CASE WHEN #UseSelectSyntax = 1
THEN CASE WHEN #RowNo > 1 THEN N'UNION' + CASE WHEN #FormatCode = 1 THEN #CrLf ELSE N' ' END ELSE N'' END
ELSE CASE WHEN #RowNo > 1 THEN N',' ELSE N' ' END END
+ #TableRow;
FETCH NEXT FROM DataCursor INTO #TableRow;
END
CLOSE DataCursor;
DEALLOCATE DataCursor;
IF #GenerateStatementTerminator = 1
BEGIN
INSERT INTO #Results
SELECT N';';
END
IF #GenerateGo = 1
BEGIN
INSERT INTO #Results
SELECT N'GO';
END
END
IF #PopulateIdentityColumn = 1
BEGIN
INSERT INTO #Results
SELECT N'SET IDENTITY_INSERT ' + COALESCE(#TargetObjectName,#ObjectName) + N' OFF'
END
IF #FormatCode = 1
BEGIN
INSERT INTO #Results
SELECT N''; -- An empty line at the end
END
IF #PrintGeneratedCode = 1
BEGIN
DECLARE #LongRows bigint;
SET #LongRows = (SELECT COUNT(*) FROM #Results WHERE LEN(TableRow) > 4000);
IF #LongRows > 0
AND #ShowWarnings = 1
BEGIN
PRINT(N'--*************************');
IF #LongRows = 1
PRINT(N'--WARNING: ' + CONVERT(nvarchar(max), #LongRows) + N' Row is very long and will be chopped at every 4000 character.')
ELSE
PRINT(N'--WARNING: ' + CONVERT(nvarchar(max), #LongRows) + N' Rows are very long and will be chopped at every 4000 character.');
PRINT(N'-- If this is an issue then the workaround is to use #PrintGeneratedCode = 0 and output "Result to Grid" in SSMS.');
PRINT(N'--*************************');
END
DECLARE ResultsCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT TableRow
FROM #Results
FOR READ ONLY
;
OPEN ResultsCursor;
FETCH NEXT FROM ResultsCursor INTO #TableRow;
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #CurrentEnd bigint; -- track the length of the next sub-string
DECLARE #Offset tinyint; -- tracks the amount of offset needed
SET #TableRow = REPLACE(REPLACE(#TableRow, CHAR(13) + CHAR(10), CHAR(10)), CHAR(13), CHAR(10));
WHILE LEN(#TableRow) > 1
BEGIN
IF CHARINDEX(CHAR(10), #TableRow) BETWEEN 1 AND 4000
BEGIN
SET #CurrentEnd = CHARINDEX(CHAR(10), #TableRow) - 1;
SET #Offset = 2;
END
ELSE
BEGIN
SET #CurrentEnd = 4000;
SET #Offset = 1;
END
PRINT(SUBSTRING(#TableRow, 1, #CurrentEnd));
SET #TableRow = SUBSTRING(#TableRow, #CurrentEnd + #Offset, LEN(#TableRow))
END
FETCH NEXT FROM ResultsCursor INTO #TableRow;
END
CLOSE ResultsCursor;
DEALLOCATE ResultsCursor;
END ELSE BEGIN
SELECT *
FROM #Results;
END
END
GO
----==============================
--ONCE SP Created run The following Code With Table_Name..
DECLARE #Name NVARCHAR(261)='Table_Name';
DECLARE TableCursor CURSOR LOCAL FAST_FORWARD FOR
SELECT QUOTENAME(s.name) + '.' + QUOTENAME(t.name) ObjectName
FROM sys.tables t
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
WHERE t.name NOT LIKE 'sys%' AND t.name='Table_Name'
FOR READ ONLY
;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO #Name;
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE dbo.GenerateInsert #ObjectName = #Name;
FETCH NEXT FROM TableCursor INTO #Name;
END
CLOSE TableCursor;
DEALLOCATE TableCursor;

Related

A list of read to file / write to file keywords for SQL Server

We're migrating a SQL Server and as part of preparing for this we need to know about any file access it will be doing to paths that may not exist any more.
There is a large amount of T-SQL we would need to go through to search for any reads / writes to file paths. I'm thinking I could search all of our T-SQL for keywords that do those operations to find potential problems.
Two example keywords I can think of are
OPENROWSET
QUERYOUT
Is there any others?
You want a list of keywords that might be in code somewhere that hard-codes a defunct path? Well, the list is very long... bulk insert, xp_cmdshell, sys.dm_os_file_exists, sp_OACreate, xp_fileexist, create database, alter database, restore database, backup database, ... enumerating this and somehow being sure you got them all will be difficult. It will certainly be easier to find all of the hard-coded paths (assuming you know the list of paths that have been removed) than to find all the keywords that might be involved in referencing them.
If you have removed a mapped drive called X:\, for example, it is much easier to search all procedures / job steps / etc. for %X:\% than it is to find all the places where you use BULK INSERT and then check each one of those to see if they reference X:\.
In either case, I put together this handy search procedure that searches code for a specific string. You can certainly use it to find all instances of BULK INSERT, and all instances of xp_cmdshell, etc. But again it will be a lot easier to search for the explicit paths / drive letters / network shares, and even use that as an opportunity to change the way your code references paths that can change (e.g. put them in config or in a table, instead of hard-coding them anywhere).
CREATE PROCEDURE dbo.FindStringInModules
#search_string nvarchar(4000),
#database_list nvarchar(max) = NULL,
#case_sensitive bit = 0,
#search_jobs bit = 0,
#search_job_and_step_names bit = 0,
#search_schema_names bit = 0,
#search_object_names bit = 0,
#search_column_names bit = 0,
#search_parameter_names bit = 0,
#search_system_objects bit = 0,
#search_system_databases bit = 0,
#search_everything bit = 0,
#debug bit = 0
AS
BEGIN
SET NOCOUNT ON;
IF #search_everything = 1
BEGIN
SELECT
#search_jobs = 1,
#search_job_and_step_names = 1,
#search_object_names = 1,
#search_schema_names = 1,
#search_column_names = 1,
#search_parameter_names = 1,
#search_system_objects = 1,
#search_system_databases = 1;
END
DECLARE #sql nvarchar(max),
#template nvarchar(max),
#exec nvarchar(1024),
#all_text nvarchar(128),
#coll_text nvarchar(128);
SELECT #sql = N'',
#template = N'',
#all_text = CASE #search_system_objects
WHEN 1 THEN N'all_' ELSE N'' END,
#coll_text = CASE #case_sensitive
WHEN 1 THEN N'Latin1_General_100_CS_AS_SC'
WHEN 0 THEN N'Latin1_General_100_CI_AS_SC'
END;
CREATE TABLE #o
(
[database] nvarchar(130),
[schema] nvarchar(130),
[object] nvarchar(130),
[type] nvarchar(130),
create_date datetime,
modify_date datetime,
column_name nvarchar(130),
param_name nvarchar(130),
definition xml
);
SET #search_string = N'%' + #search_string + N'%';
SET #template = N'
SELECT [database] = DB_NAME(),
[schema] = s.name,
[object] = o.name,
[type] = o.type_desc,
o.create_date,
o.modify_date,
[column_name] = $col$,
[param_name] = $param$,
definition = CONVERT(xml, ''<?query -- '' + QUOTENAME(DB_NAME())
+ CHAR(13) + CHAR(10) + OBJECT_DEFINITION(o.object_id)
+ CHAR(13) + CHAR(10) + ''--'' + CHAR(63) + ''>'')
FROM sys.$all$objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]';
SET #sql = #sql + REPLACE(REPLACE(#template, N'$col$', N'NULL'), N'$param$', N'NULL')
+ N'
' + N' WHERE OBJECT_DEFINITION(o.[object_id]) COLLATE $coll$
' + N' LIKE #s COLLATE $coll$';
SET #sql = #sql + CASE #search_schema_names WHEN 1 THEN N'
OR s.name COLLATE $coll$
LIKE #s COLLATE $coll$' ELSE N'' END;
SET #sql = #sql + CASE #search_object_names WHEN 1 THEN N'
OR o.name COLLATE $coll$
LIKE #s COLLATE $coll$' ELSE N'' END;
SET #sql = #sql + CASE #search_column_names WHEN 1 THEN N';
' + REPLACE(REPLACE(#template, N'$col$', N'c.name'),N'$param$',N'NULL')
+ N'
INNER JOIN sys.$all$columns AS c ON o.[object_id] = c.[object_id]
AND c.name COLLATE $coll$
LIKE #s COLLATE $coll$;' ELSE N'' END;
SET #sql = #sql + CASE #search_parameter_names WHEN 1 THEN N';
' + REPLACE(REPLACE(#template, N'$col$', N'NULL'),N'$param$',N'p.name')
+ N'
INNER JOIN sys.$all$parameters AS p ON o.[object_id] = p.[object_id]
AND p.name COLLATE $coll$
LIKE #s COLLATE $coll$;' ELSE N'' END;
SET #sql = REPLACE(REPLACE(#sql, N'$coll$', #coll_text), N'$all$', #all_text);
DECLARE #db sysname, #c cursor;
SET #c = cursor FORWARD_ONLY STATIC READ_ONLY FOR
SELECT QUOTENAME(name) FROM sys.databases AS d
LEFT OUTER JOIN dbo.fn_split(#database_list, N',') AS s ON 1 = 1
WHERE
(
LOWER(d.name) = LOWER(LTRIM(RTRIM(s.value)))
OR NULLIF(RTRIM(#database_list), N'') IS NULL
)
AND d.database_id >= CASE #search_system_databases
WHEN 1 THEN 1 ELSE 5 END
AND d.database_id < 32767
AND d.state = 0;
OPEN #c;
FETCH NEXT FROM #c INTO #db;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #exec = #db + N'.sys.sp_executesql';
IF #debug = 1
BEGIN
RAISERROR(N'Running dynamic SQL on %s:', 1, 0, #db);
PRINT #sql;
END
ELSE
BEGIN
INSERT #o
(
[database],
[schema],
[object],
[type],
create_date,
modify_date,
column_name,
param_name,
definition
)
EXEC #exec #sql, N'#s nvarchar(4000)', #s = #search_string;
END
FETCH NEXT FROM #c INTO #db;
END
IF #debug = 0
BEGIN
SELECT [database],
[schema],
[object],
[type],
create_date,
modify_date,
column_name,
param_name,
definition
FROM #o
ORDER BY [database], [schema], [object], [column_name], [param_name];
END
/* jobs */
IF #search_jobs = 1
BEGIN
SET #template = N'SELECT
job_name = j.name,
s.step_id,
s.step_name,
j.date_created,
j.date_modified,
[command_with_use] = CONVERT(xml, N''<?query -- ''
+ QUOTENAME(s.database_name)
+ CHAR(13) + CHAR(10) + s.[command]
+ CHAR(13) + CHAR(10) + ''--'' + CHAR(63) + ''>'')
FROM msdb.dbo.sysjobs AS j
INNER JOIN msdb.dbo.sysjobsteps AS s
ON j.job_id = s.job_id
WHERE s.command COLLATE $coll$
LIKE #s COLLATE $coll$'
+ CASE #search_job_and_step_names WHEN 1 THEN
N' OR j.name COLLATE $coll$
LIKE #s COLLATE $coll$
OR s.step_name COLLATE $coll$
LIKE #s COLLATE $coll$'
ELSE N'' END
+ N' ORDER BY j.name, s.step_id;';
SET #sql = REPLACE(#template, N'$coll$', #coll_text);
IF #debug = 1
BEGIN
PRINT N'Running this for jobs:';
PRINT #sql;
END
ELSE
BEGIN
EXEC sys.sp_executesql #sql, N'#s nvarchar(4000)', #s = #search_string;
END
END
END
GO

Change Nested Cursor stored procedure to Nested loop

I have a stored procedure which is currently using nested cursors to build up views using database, table, column parameters. I need this to be changed to a while loop query instead. I understand the results are the same but we just prefer not to use cursors.
This seem very tricky due to the dynamic SQL.
ALTER PROCEDURE [dbo].[spReCreateCommonViews_AK]
AS
DECLARE #Exec INT = 1, #Print INT = 2
-- DECLARE #debug INT = #Exec
DECLARE #debug INT = #Print
DECLARE #Sql VARCHAR(MAX),
#SourceName VARCHAR(100),
#DatabaseName VARCHAR(100),
#CompanyName VARCHAR(100),
#ColumnCursor VARCHAR(800),
#TableId INT,
#TableName VARCHAR(100),
#ColumnType INT,
#ColumnName VARCHAR(100),
#ColumnList VARCHAR(MAX) = '',
#CreateViewSQL VARCHAR(MAX)
/** COMPANIES ********/
DECLARE CompaniesCursor CURSOR FOR
SELECT
[Database],
REPLACE(REPLACE(REPLACE([Name], '.', '_'), '/', '_'), '''', '_') AS [Name],
CASE
WHEN RIGHT([Source], 7) = '_SOURCE'
THEN '[' + [Source] + '].[' + [Database] + ']'
ELSE '[' + [Database] + ']'
END AS [Source]
FROM
Company
OPEN CompaniesCursor
FETCH NEXT FROM CompaniesCursor INTO #DatabaseName, #CompanyName, #SourceName
WHILE ##fetch_status = 0
BEGIN
/** TABLES ***********/
SELECT #Sql = 'DECLARE TablesCursor CURSOR FOR
select
o.[id] as TableId,
o.[name] as TableName
from '+#SourceName+'.dbo.sysobjects o
inner join '+#SourceName+'.dbo.[Object] t
on o.[name] = replace(replace(replace(t.[Name],''.'',''_''),''/'',''_''),'''''''',''_'')
and t.[Company Name] = ''''
and t.[Type] = 0
where o.[name] <> ''Company''
and o.[name] not like ''' + #CompanyName + '$%''
and o.type = ''U''
order by o.[name]
'
exec(#Sql)
open TablesCursor
fetch next from TablesCursor into #TableId, #TableName
while ##fetch_status = 0
begin
/** COLUMNS ************************************************************/
select #ColumnCursor =
'
declare ColumnsCursor cursor
for
select ''['' + [name] + '']'' as ColumnName, xtype as ColumnType
from '+#SourceName+'.dbo.syscolumns
where [id] = ' + convert(varchar, #TableId) + '
order by colid
'
exec(#ColumnCursor)
open ColumnsCursor
fetch next from ColumnsCursor into #ColumnName, #ColumnType
while ##fetch_status = 0
begin
select #ColumnList = #ColumnList + #ColumnName + case when #ColumnType in (35, 99, 167, 175, 231, 239) then ' collate database_default as ' + #ColumnName + ', ' else ', ' end
-----------------------------
fetch next from ColumnsCursor into #ColumnName, #ColumnType
end
close ColumnsCursor
deallocate ColumnsCursor
-----------------------------
select #CreateViewSQL= 'if object_id(N'''+#CompanyName+'$' + #TableName + ''', N''V'') is not null drop view ['+#CompanyName+'$' + #TableName + ']'
if #debug & #Print = #Print print(#CreateViewSQL)
if #debug & #Exec = #Exec exec (#CreateViewSQL)
select #CreateViewSQL= 'create view ['+#CompanyName+'$' + #TableName + '] as select ' + left(#ColumnList,len(#ColumnList)-1) + ' from ' + #SourceName + '.dbo.[' + #TableName + ']'
if #debug & #Print = #Print print(#CreateViewSQL)
if #debug & #Exec = #Exec exec (#CreateViewSQL)
select #ColumnList = ''
-----------------------------
fetch next from TablesCursor into #TableId, #TableName
end
close TablesCursor
deallocate TablesCursor
------------------------------
select #Sql = '
insert into [Object] (
[Type],
[Company Name],
[ID],
[Name],
[Modified],
[Compiled],
[BLOB Reference],
[BLOB Size],
[DBM Table No_],
[Date],
[Time],
[Version List]
)
select
o.[Type],
'''+#CompanyName+''' as [Company Name],
o.[ID],
o.[Name] collate database_default,
o.[Modified],
o.[Compiled],
o.[BLOB Reference],
o.[BLOB Size],
o.[DBM Table No_],
o.[Date],
o.[Time],
o.[Version List] collate database_default
from '+#SourceName+'.dbo.Object o
where o.[Name] <> ''Company''
and o.[Company Name] = ''''
and o.[Type] = 0
and not exists (
select c.*
from [Object] c
where c.[Name] = o.[Name] collate database_default
and c.[Company Name] = '''+#CompanyName+'''
and c.[Type] = 0
and c.[ID] = o.[ID]
)
'
if #debug & #Print = #Print
print(#Sql)
if #debug & #Exec = #Exec
exec (#Sql)
-----------------------------
fetch next from CompaniesCursor into #DatabaseName, #CompanyName, #SourceName
end
close CompaniesCursor
deallocate CompaniesCursor
-----------------------------

SQL Server - Dynamic Table Name as Variable

I have been having problems trying to create tables with dynamic name. I keep getting these errors:
Msg 102, Level 15, State 1, Procedure SP_SearchTables, Line 159
Incorrect syntax near '#tablename'.
Msg 1087, Level 15, State 2, Procedure SP_SearchTables, Line 165
Must declare the table variable "#tablename".
Msg 1087, Level 15, State 2, Procedure SP_SearchTables, Line 171
Must declare the table variable "#tablename".
As you can see in the stored procedure, before this changes I had SearchTMP instead #tablename, but I don't want to give a fixed name, I want to give a dynamic name. With that in mind, I gave a name and some random numbers, but it keeps giving me the errors I showed previously, could you please help me?
I will post my stored procedure.
ALTER PROCEDURE [dbo].[SearchTables]
#SearchStr NVARCHAR(60),
#GenerateSQLOnly BIT = 0,
#SchemaNames VARCHAR(500) ='%'
AS
SET NOCOUNT ON
DECLARE #MatchFound BIT
SELECT #MatchFound = 0
DECLARE #CheckTableNames TABLE (Schemaname sysname, Tablename sysname)
DECLARE #SearchStringTbl TABLE (SearchString VARCHAR(500))
DECLARE #SQLTbl TABLE
(
Tablename SYSNAME,
WHEREClause VARCHAR(MAX),
SQLStatement VARCHAR(MAX),
Execstatus BIT
)
DECLARE #SQL VARCHAR(MAX)
DECLARE #TableParamSQL VARCHAR(MAX)
DECLARE #SchemaParamSQL VARCHAR(MAX)
DECLARE #TblSQL VARCHAR(MAX)
DECLARE #tmpTblname sysname
DECLARE #ErrMsg VARCHAR(100)
IF LTRIM(RTRIM(#SchemaNames)) =''
BEGIN
SELECT #SchemaNames = '%'
END
IF CHARINDEX(',',#SchemaNames) > 0
SELECT #SchemaParamSQL = 'SELECT ''' + REPLACE(#SchemaNames,',','''as SchemaName UNION SELECT ''') + ''''
ELSE
SELECT #SchemaParamSQL = 'SELECT ''' + #SchemaNames + ''' as SchemaName '
SELECT #TblSQL = 'SELECT SCh.NAME,T.NAME
FROM SYS.TABLES T
JOIN SYS.SCHEMAS SCh ON SCh.SCHEMA_ID = T.SCHEMA_ID
INNER JOIN [DynaForms].[dbo].[Enums_Tables] et ON (et.Id = T.NAME COLLATE Latin1_General_CI_AS) '
INSERT INTO #CheckTableNames (Schemaname, Tablename)
EXEC (#TblSQL)
IF NOT EXISTS(SELECT 1 FROM #CheckTableNames)
BEGIN
SELECT #ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
IF LTRIM(RTRIM(#SearchStr)) =''
BEGIN
SELECT #ErrMsg = 'Please specify the search string in #SearchStr Parameter'
PRINT #ErrMsg
RETURN
END
ELSE
BEGIN
SELECT #SearchStr = REPLACE(#SearchStr,',,,',',#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,',,','#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,'''','''''')
SELECT #SQL = 'SELECT ''' + REPLACE(#SearchStr,',','''as SearchString UNION SELECT ''') + ''''
INSERT INTO #SearchStringTbl (SearchString)
EXEC(#SQL)
UPDATE #SearchStringTbl
SET SearchString = REPLACE(SearchString ,'#DOUBLECOMMA#',',')
END
INSERT INTO #SQLTbl (Tablename, WHEREClause)
SELECT
QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME),
(SELECT '[' + SC.Name + ']' + ' LIKE ''' + REPLACE(SearchSTR.SearchString,'''','''''') + ''' OR ' + CHAR(10)
FROM SYS.columns SC
JOIN SYS.types STy ON STy.system_type_id = SC.system_type_id
AND STy.user_type_id =SC.user_type_id
CROSS JOIN #SearchStringTbl SearchSTR
WHERE STY.name IN ('varchar', 'char', 'nvarchar', 'nchar', 'text')
AND SC.object_id = ST.object_id
ORDER BY SC.name
FOR XML PATH('')
)
FROM
SYS.tables ST
JOIN
#CheckTableNames chktbls ON chktbls.Tablename = ST.name
JOIN
SYS.schemas SCh ON ST.schema_id = SCh.schema_id
AND Sch.name = chktbls.Schemaname
WHERE
ST.name <> 'SearchTMP'
GROUP BY
ST.object_id, QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME) ;
DECLARE #numbers VARCHAR(MAX)
SET #numbers = CONVERT(NUMERIC(12, 0), RAND() * 899999999999) + 100000000000
DECLARE #tablename VARCHAR(MAX)
SET #tablename = 'SearchTMP' + #numbers
UPDATE #SQLTbl
SET SQLStatement = N'SELECT * INTO ' + #tablename +' FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5)
DELETE FROM #SQLTbl
WHERE WHEREClause IS NULL
DECLARE #output TABLE (Id VARCHAR(50), Name VARCHAR(100))
WHILE EXISTS (SELECT 1 FROM #SQLTbl WHERE ISNULL(Execstatus ,0) = 0)
BEGIN
SELECT TOP 1 #tmpTblname = Tablename , #SQL = SQLStatement
FROM #SQLTbl
WHERE ISNULL(Execstatus ,0) = 0
IF #GenerateSQLOnly = 0
BEGIN
IF OBJECT_ID('#tablename','U') IS NOT NULL
DROP TABLE #tablename
EXEC (#SQL)
IF EXISTS(SELECT 1 FROM #tablename)
BEGIN
--SELECT parsename(#tmpTblname,1) FROM SearchTMP
SELECT #MatchFound = 1
INSERT INTO #output (Id, Name)
SELECT *
FROM [DynaForms].[dbo].[Enums_Tables]
WHERE id IN (SELECT parsename(#tmpTblname, 1) FROM #tablename)
END
END
ELSE
BEGIN
PRINT REPLICATE('-',100)
PRINT #tmpTblname
PRINT REPLICATE('-',100)
PRINT replace(#SQL,'INTO #tablename','')
END
UPDATE #SQLTbl
SET Execstatus = 1
WHERE Tablename = #tmpTblname
END
SELECT * FROM #output
--Select * from #SQLTbl
IF #MatchFound = 0
BEGIN
SELECT #ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
SET NOCOUNT OFF
Edit
I changed my stored procedure to have dynamic sql but it gives me this error:
Msg 214, Level 16, State 2, Procedure sp_executesql, Line 1
Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'.
I believe the problem is in my subquery, but I can't seen to make it work, could you please help me? The subquery is here:
DECLARE #SQLSUBQUERY VARCHAR(max);
SELECT #SQLSUBQUERY = 'SELECT * FROM [DynaForms].[dbo].[Enums_Tables] ';
SELECT #SQLSUBQUERY = #SQLSUBQUERY + 'WHERE id IN (SELECT parsename(#tmpTblname,1) FROM #tablename)';
INSERT INTO #output (Id, Name)
EXEC sp_executesql #SQLSUBQUERY
Full code here:
ALTER PROCEDURE [dbo].[SP_SearchTables]
#SearchStr NVARCHAR(60),
#GenerateSQLOnly Bit = 0,
#SchemaNames VARCHAR(500) ='%'
AS
SET NOCOUNT ON
DECLARE #MatchFound BIT
SELECT #MatchFound = 0
DECLARE #CheckTableNames TABLE (Schemaname sysname, Tablename sysname)
DECLARE #SearchStringTbl TABLE (SearchString VARCHAR(500))
DECLARE #SQLTbl TABLE (Tablename SYSNAME,
WHEREClause VARCHAR(MAX),
SQLStatement VARCHAR(MAX),
Execstatus BIT)
DECLARE #SQL VARCHAR(MAX)
DECLARE #TableParamSQL VARCHAR(MAX)
DECLARE #SchemaParamSQL VARCHAR(MAX)
DECLARE #TblSQL VARCHAR(MAX)
DECLARE #tmpTblname sysname
DECLARE #ErrMsg VARCHAR(100)
IF LTRIM(RTRIM(#SchemaNames)) =''
BEGIN
SELECT #SchemaNames = '%'
END
IF CHARINDEX(',',#SchemaNames) > 0
SELECT #SchemaParamSQL = 'SELECT ''' + REPLACE(#SchemaNames,',','''as SchemaName UNION SELECT ''') + ''''
ELSE
SELECT #SchemaParamSQL = 'SELECT ''' + #SchemaNames + ''' as SchemaName '
SELECT #TblSQL = 'SELECT SCh.NAME,T.NAME
FROM SYS.TABLES T
JOIN SYS.SCHEMAS SCh
ON SCh.SCHEMA_ID = T.SCHEMA_ID
INNER JOIN [DynaForms].[dbo].[Enums_Tables] et on
(et.Id = T.NAME COLLATE Latin1_General_CI_AS) '
INSERT INTO #CheckTableNames (Schemaname, Tablename)
EXEC(#TblSQL)
IF NOT EXISTS(SELECT 1 FROM #CheckTableNames)
BEGIN
SELECT #ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
IF LTRIM(RTRIM(#SearchStr)) =''
BEGIN
SELECT #ErrMsg = 'Please specify the search string in #SearchStr Parameter'
PRINT #ErrMsg
RETURN
END
ELSE
BEGIN
SELECT #SearchStr = REPLACE(#SearchStr,',,,',',#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,',,','#DOUBLECOMMA#')
SELECT #SearchStr = REPLACE(#SearchStr,'''','''''')
SELECT #SQL = 'SELECT ''' + REPLACE(#SearchStr,',','''as SearchString UNION SELECT ''') + ''''
INSERT INTO #SearchStringTbl
(SearchString)
EXEC(#SQL)
UPDATE #SearchStringTbl
SET SearchString = REPLACE(SearchString ,'#DOUBLECOMMA#',',')
END
INSERT INTO #SQLTbl (Tablename, WHEREClause)
SELECT
QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME),
(SELECT '[' + SC.Name + ']' + ' LIKE ''' + REPLACE(SearchSTR.SearchString,'''','''''') + ''' OR ' + CHAR(10)
FROM SYS.columns SC
JOIN SYS.types STy ON STy.system_type_id = SC.system_type_id
AND STy.user_type_id =SC.user_type_id
CROSS JOIN #SearchStringTbl SearchSTR
WHERE
STY.name in ('varchar','char','nvarchar','nchar','text')
AND SC.object_id = ST.object_id
ORDER BY SC.name
FOR XML PATH('')
)
FROM SYS.tables ST
JOIN #CheckTableNames chktbls
ON chktbls.Tablename = ST.name
JOIN SYS.schemas SCh
ON ST.schema_id = SCh.schema_id
AND Sch.name = chktbls.Schemaname
WHERE ST.name <> 'SearchTMP'
GROUP BY ST.object_id, QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME) ;
declare #numbers varchar(MAx)
set #numbers = convert(numeric(12,0),rand() * 899999999999) + 100000000000
declare #tablename varchar(MAX)
set #tablename = 'SearchTMP' + #numbers
UPDATE #SQLTbl
SET SQLStatement = N'SELECT * INTO ' + #tablename +' FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5)
DELETE FROM #SQLTbl
WHERE WHEREClause IS NULL
DECLARE #output TABLE (Id VARCHAR(50), Name VARCHAR(100))
WHILE EXISTS (SELECT 1 FROM #SQLTbl WHERE ISNULL(Execstatus ,0) = 0)
BEGIN
SELECT TOP 1 #tmpTblname = Tablename , #SQL = SQLStatement
FROM #SQLTbl
WHERE ISNULL(Execstatus ,0) = 0
IF #GenerateSQLOnly = 0
BEGIN
DECLARE #SQLs NVARCHAR(MAX)
SELECT #SQLs = 'DROP TABLE dbo.' + QUOTENAME(#tablename) + '';
IF OBJECT_ID(''+#tablename+'','U') IS NOT NULL
EXEC sp_executesql #SQLs;
EXEC (#SQL)
--IF EXISTS(SELECT 1 FROM #tablename)
BEGIN
--SELECT parsename(#tmpTblname,1) FROM SearchTMP
SELECT #MatchFound = 1
DECLARE #SQLSUBQUERY VARCHAR(max);
SELECT #SQLSUBQUERY = 'SELECT * FROM [DynaForms].[dbo].[Enums_Tables] ';
SELECT #SQLSUBQUERY = #SQLSUBQUERY + 'WHERE id IN (SELECT parsename(#tmpTblname,1) FROM #tablename)';
INSERT INTO #output (Id, Name)
EXEC sp_executesql #SQLSUBQUERY
--Select * from [DynaForms].[dbo].[Enums_Tables] where id in (SELECT parsename(#tmpTblname,1) FROM #tablename)
END
END
ELSE
BEGIN
PRINT REPLICATE('-',100)
PRINT #tmpTblname
PRINT REPLICATE('-',100)
PRINT replace(#SQL,'INTO #tablename','')
END
UPDATE #SQLTbl
SET Execstatus = 1
WHERE Tablename = #tmpTblname
END
SELECT * FROM #output
--Select * from #SQLTbl
IF #MatchFound = 0
BEGIN
SELECT #ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter'
PRINT #ErrMsg
RETURN
END
SET NOCOUNT OFF
There are at least these errors:
IF OBJECT_ID('#tablename','U') IS NOT NULL
This is wrong because check for a table with the name #tablename
IF EXISTS(SELECT 1 FROM #tablename)
This produce the error you've got.
DROP TABLE does not accept variable, use dynamic sql to to your drop

Conversion failed when converting date and/or time from character string?

I use pivot table but when I execute I got this error please help me I am stuck on this thanks in advance sorry if any mistake and please also tell me that how to handle string in string in sql server I use " '' '',''-'' " but not sure it is correct or not please help me as soon as posible here are the query
SELECT #SQL = 'SELECT '
WHile #I <= #Months
BEGIN
SET #YearMonth = REPLACE(LTRIM(SUBSTRING(CONVERT(VARCHAR, DateAdd(Month, #I, #StartDate), 13), 3,9)), ' ', '-')
SET #ColumnText = #YearMonth
SET #SQL = #SQL + 'ISNULL([' + #YearMonth + '], 0.00) as ''' + #ColumnText + ''','
SET #I = #I +1
END
Set #I = 0
SET #SQL = #SQL + 'Product,Supplier,PackPrice,QuantityInPack,Code,SupplierID,Description,RebateAmount
FROM
(
SELECT p.NAME AS product,p.Code AS Code,P.Description as Description,oi.PackPrice,oi.QuantityInPack AS Packsize,S.ID AS SupplierID,s.[Name] AS Supplier,
CASE when oi.RebateType=2 then (oi.PackPrice*oi.RebateAmount)/100 ELSE oi.RebateAmount END AS RebateAmount ,o.Total as TotalSale,
REPLACE(LTRIM(SUBSTRING(CONVERT(VARCHAR, O.CreatedDate, 13), 3,9)), '' '',''-'') as tdate
FROM dbo.SCM_Product p WITH (NOLOCK)
INNER JOIN SCM_OrderItem oi WITH (NOLOCK) ON oi.ProductId = p.ID
LEFT OUTER JOIN dbo.SCM_Supplier s WITH(NoLock) ON oi.SupplierID=s.ID
LEFT OUTER JOIN SCM_Order o WITH (NOLOCK) ON o.Id = oi.ProductId AND O.Status <> 5 -- CANCELLED
AND O.Deleted = 0
WHERE ('''+#SupplierID+''' IS NULL OR s.ID IN (SELECT * FROM GetIDsTableFromIDsList(#SupplierID)))
AND ('''+#ProductID+''' IS NULL OR p.ID IN (SELECT * FROM GetIDsTableFromIDsList(#ProductID)) )
AND (o.CreatedDate >= '''+ dbo.GetDatePart(#StartDate) +''' AND o.CreatedDate <= '''+ dbo.GetDatePart(#Enddate) +''')
GROUP BY REPLACE(LTRIM(SUBSTRING(CONVERT(VARCHAR, o.CreatedDate, 13), 3,9)), '' '',''-''),
s.ID,p.Code,p.NAME,s.NAME,P.Description,oi.packPrice,oi.QuantityInPack,oi.RebateAmount,oi.RebateType,oi.PackPrice,o.Total
) SD
PIVOT
( SUM( SD.TotalSale) FOR SD.tdate IN ('
WHile #I <= #Months
BEGIN
SET #YearMonth = REPLACE(LTRIM(SUBSTRING(CONVERT(VARCHAR, DateAdd(Month, #I, #StartDate), 13), 3,9)), ' ', '-')
IF #I = #Months
BEGIN
SET #SQL = #SQL + ' [' + #YearMonth + ']'
END
ELSE
BEGIN
SET #SQL = #SQL + ' [' + #YearMonth + '],'
END
SET #I = #I +1
END
SET #SQL = #SQL + ')) as pvt
ORDER BY Supplier '
--EXEC(#SQL)
PRINT #SQL
The easiest way of doing it would be to use QUOTENAME() function,because you could easily miss quote in a large query.
Example:
DECLARE #name AS CHAR(10) = 'Revolver'
DECLARE #sql as NVARCHAR(300) = 'SELECT *
FROM Music.Album
WHERE Name ='+ QUOTENAME(#name,'''')
PRINT #sql;
or
DECLARE #name AS CHAR(10) = 'Revolver'
DECLARE #sql as NVARCHAR(300) = 'SELECT *
FROM Music.Album
WHERE Name ='''+ #name + ''''
PRINT #sql;

Is there a way to create multiple triggers in one script?

I am trying to create multiple triggers with only uploading one script into an Oracle DB / APEX workspace, and running it once.
Here is a brief script compared to the one im trying to use:
create or replace trigger "BI_TEC_ROLES"
before insert on "TEC_ROLES"
for each row
begin
if :NEW."ROLE_ID" is null then
select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual;
end if;
end;
create or replace trigger "BI_TEC_STATUSES"
before insert on "TEC_STATUSES"
for each row
begin
if :NEW."STATUS_ID" is null then
select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual;
end if;
end;
create or replace trigger "BI_TEC_SUBS"
before insert on "TEC_SUBS"
for each row
begin
if :NEW."SUB_ID" is null then
select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual;
end if;
end;
I have tried putting GO in between each individual block, but still only creates the first trigger then gives me an error for the second saying:
Error(7,1): PLS-00103: Encountered the symbol "CREATE"
I am hoping that it is possible to do this. Thank you very much for your time and interest =)
Add a forward slash on a new line after each trigger to execute the command in the buffer:
create trigger...
...
end;
/
Put a slash '/' as the first character on a blank line between each trigger statement. This is the SQL*PLUS equivalent of 'go'.
Yes we can execute multiple procedure/trigger/function in single script using the FORWARD SLASH / inside the sql file.
Like below:
create or replace trigger "BI_TEC_ROLES"
before insert on "TEC_ROLES"
for each row
begin
if :NEW."ROLE_ID" is null then
select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual;
end if;
end;
/
create or replace trigger "BI_TEC_STATUSES"
before insert on "TEC_STATUSES"
for each row
begin
if :NEW."STATUS_ID" is null then
select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual;
end if;
end;
/
create or replace trigger "BI_TEC_SUBS"
before insert on "TEC_SUBS"
for each row
begin
if :NEW."SUB_ID" is null then
select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual;
end if;
end;
/
Then oracle will consider it as new statement/block.
Place a forward slash
/
between the two statements on a separate line.
Oracle will then accept it as a new statement
--Parameter:
-- #InclDrop bit
-- Possible values
-- 0 - Script to drop the triggers is not generated.
-- 1 - Script to drip the triggers is generated.
SET ansi_nulls ON
go
SET quoted_identifier ON
go
ALTER PROCEDURE [dbo].[Createscriptofalltriggers]
#InclDrop BIT =1
AS
DECLARE #SQL VARCHAR(8000),
#Text NVARCHAR(4000),
#BlankSpaceAdded INT,
#BasePos INT,
#CurrentPos INT,
#TextLength INT,
#LineId INT,
#MaxID INT,
#AddOnLen INT,
#LFCR INT,
#DefinedLength INT,
#SyscomText NVARCHAR(4000),
#Line NVARCHAR(1000),
#UserName SYSNAME,
#ObjID INT,
#OldTrigID INT
SET nocount ON
SET #DefinedLength = 1000
SET #BlankSpaceAdded = 0
IF #InclDrop <> 0
SET #InclDrop =1
-- This Part Validated the Input parameters
DECLARE #Triggers TABLE
(
username SYSNAME NOT NULL,
trigname SYSNAME NOT NULL,
objid INT NOT NULL
)
DECLARE #TrigText TABLE
(
objid INT NOT NULL,
lineid INT NOT NULL,
linetext NVARCHAR(1000) NULL
)
INSERT INTO #Triggers
(username,
trigname,
objid)
SELECT DISTINCT A.NAME,
B.NAME,
B.id
FROM dbo.sysusers A,
dbo.sysobjects B,
dbo.syscomments C
WHERE A.uid = B.uid
AND B.type = 'Tr'
AND B.id = C.id
AND C.encrypted = 0
IF EXISTS(SELECT C.*
FROM syscomments C,
sysobjects O
WHERE O.id = C.id
AND O.type = 'Tr'
AND C.encrypted = 1)
BEGIN
PRINT '/*'
PRINT 'The following encrypted triggers were found'
PRINT 'The procedure could not write the script for it'
SELECT DISTINCT A.NAME,
B.NAME,
B.id
FROM dbo.sysusers A,
dbo.sysobjects B,
dbo.syscomments C
WHERE A.uid = B.uid
AND B.type = 'Tr'
AND B.id = C.id
AND C.encrypted = 1
PRINT '*/'
END
DECLARE ms_crs_syscom CURSOR local forward_only FOR
SELECT T.objid,
C.text
FROM #Triggers T,
dbo.syscomments C
WHERE T.objid = C.id
ORDER BY T.objid,
C.colid
FOR READ only
SELECT #LFCR = 2
SELECT #LineId = 1
OPEN ms_crs_syscom
SET #OldTrigID = -1
FETCH next FROM ms_crs_syscom INTO #ObjID, #SyscomText
WHILE ##fetch_status = 0
BEGIN
SELECT #BasePos = 1
SELECT #CurrentPos = 1
SELECT #TextLength = Len(#SyscomText)
IF #ObjID <> #OldTrigID
BEGIN
SET #LineID = 1
SET #OldTrigID = #ObjID
END
WHILE #CurrentPos != 0
BEGIN
--Looking for end of line followed by carriage return
SELECT #CurrentPos = Charindex(Char(13) + Char(10), #SyscomText,
#BasePos)
--If carriage return found
IF #CurrentPos != 0
BEGIN
WHILE ( Isnull(Len(#Line), 0) + #BlankSpaceAdded
+ #CurrentPos - #BasePos + #LFCR ) >
#DefinedLength
BEGIN
SELECT #AddOnLen = #DefinedLength - (
Isnull(Len(#Line),
0
) +
#BlankSpaceAdded )
INSERT #TrigText
VALUES ( #ObjID,
#LineId,
Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText, #BasePos,
#AddOnLen),
N''))
SELECT #Line = NULL,
#LineId = #LineId + 1,
#BasePos = #BasePos + #AddOnLen,
#BlankSpaceAdded = 0
END
SELECT #Line = Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText, #BasePos,
#CurrentPos
-#BasePos +
#LFCR),
N'')
SELECT #BasePos = #CurrentPos + 2
INSERT #TrigText
VALUES( #ObjID,
#LineId,
#Line )
SELECT #LineId = #LineId + 1
SELECT #Line = NULL
END
ELSE
--else carriage return not found
BEGIN
IF #BasePos <= #TextLength
BEGIN
/*If new value for #Lines length will be > then the
**defined length
*/
WHILE ( Isnull(Len(#Line), 0) + #BlankSpaceAdded
+ #TextLength - #BasePos + 1 ) >
#DefinedLength
BEGIN
SELECT #AddOnLen = #DefinedLength - (
Isnull(Len(#Line),
0
) +
#BlankSpaceAdded )
INSERT #TrigText
VALUES ( #ObjID,
#LineId,
Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText,
#BasePos,
#AddOnLen),
N''))
SELECT #Line = NULL,
#LineId = #LineId + 1,
#BasePos = #BasePos + #AddOnLen,
#BlankSpaceAdded = 0
END
SELECT #Line = Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText,
#BasePos,
#TextLength
-#BasePos+1
), N'')
IF Len(#Line) < #DefinedLength
AND Charindex(' ', #SyscomText, #TextLength + 1)
> 0
BEGIN
SELECT #Line = #Line + ' ',
#BlankSpaceAdded = 1
END
END
END
END
FETCH next FROM ms_crs_syscom INTO #ObjID, #SyscomText
END
IF #Line IS NOT NULL
INSERT #TrigText
VALUES( #ObjID,
#LineId,
#Line )
CLOSE ms_crs_syscom
PRINT '-- You should run this result under dbo if your triggers belong to multiple users'
PRINT ''
IF #InclDrop = 1
BEGIN
PRINT '-- Dropping the Triggers'
PRINT ''
SELECT 'If exists(Select * from sysObjects where id =Object_ID(''['
+ username + '].[' + trigname
+ ']'') and ObjectProperty(Object_ID(''['
+ username + '].[' + trigname + ']''), ''ISTRIGGER'')=1) Drop Trigger ['
+ username + '].[' + trigname + '] ' + Char(13)
+ Char(10) + 'GO' + Char(13) + Char(10) + Char(13)
+ Char(10)
FROM #Triggers
END
PRINT '----------------------------------------------'
PRINT '-- Creation of Triggers'
PRINT ''
PRINT ''
DECLARE ms_users CURSOR local forward_only FOR
SELECT T.username,
T.objid,
Max(D.lineid)
FROM #Triggers T,
#TrigText D
WHERE T.objid = D.objid
GROUP BY T.username,
T.objid
FOR READ only
OPEN ms_users
FETCH next FROM ms_users INTO #UserName, #ObjID, #MaxID
WHILE ##fetch_status = 0
BEGIN
PRINT 'SetUser N''' + #UserName + '''' + Char(13)
+ Char(10)
SELECT '-- Text of the Trigger'= CASE lineid
WHEN 1 THEN 'GO' + Char(13) + Char(
10)
+
linetext
WHEN #MaxID THEN linetext + 'GO'
ELSE linetext
END
FROM #TrigText
WHERE objid = #ObjID
ORDER BY lineid
PRINT 'Setuser'
FETCH next FROM ms_users INTO #UserName, #ObjID, #MaxID
END
CLOSE ms_users
PRINT 'GO'
PRINT '------End ------'
DEALLOCATE ms_crs_syscom
DEALLOCATE ms_users
SET nocount ON
DECLARE #return_value INT
How to execute it:
EXEC #return_value = [dbo].[Createscriptofalltriggers]
#InclDrop = 1
SELECT 'Return Value' = #return_value
go

Resources