saveDelimitedColumns - sql
I am using the stored procedure, saveDelimitedColumns (found: http://www.virtualobjectives.com.au/sqlserver/saving_), to save data results as a .csv file. This works great with one exception...when it saves as a .csv file the column headers within excel have brackets. For example, [Client ID], I would like the column heading to be without brackets, as Client ID.
Below is the savedelimitedcolumns stored procedure and I cannot figure out if there is a way to make it so there are no brackets when it publishes as a .csv file.
Is it possible to make an alteration somewhere in the code below to accomplish this?
Thank you,
ALTER PROCEDURE [dbo].[SaveDelimitedColumns]
#PCWrite varchar(1000) = NULL,
#DBFetch varchar(4000),
#DBWhere varchar(2000) = NULL,
#DBThere varchar(2000) = NULL,
#DBUltra bit = 1,
#Delimiter varchar(100) = 'CHAR(44)', -- Default is ,
#TextQuote varchar(100) = 'CHAR(34)', -- Default is " Use SPACE(0) for none.
#Header bit = 0, -- Output header. Default is 0.
#NullQuoted bit = 0,
#DateTimeStyle tinyint = 120 -- CONVERT Date Time Style. Default is ODBC canonical yyyy-mm-dd hh:mi:ss(24h)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Return int
DECLARE #Retain int
DECLARE #Status int
SET #Status = 0
DECLARE #TPre varchar(10)
DECLARE #TDo3 tinyint
DECLARE #TDo4 tinyint
SET #TPre = ''
SET #TDo3 = LEN(#TPre)
SET #TDo4 = LEN(#TPre) + 1
DECLARE #DBAE varchar(40)
DECLARE #Task varchar(6000)
DECLARE #Bank varchar(4000)
DECLARE #Cash varchar(2000)
DECLARE #Risk varchar(2000)
DECLARE #Next varchar(8000)
DECLARE #Save varchar(8000)
DECLARE #Work varchar(8000)
DECLARE #Wish varchar(max)
DECLARE #Name varchar(100)
DECLARE #Same varchar(100)
DECLARE #Rank smallint
DECLARE #Kind varchar(20)
DECLARE #Mask bit
DECLARE #Bond bit
DECLARE #Size int
DECLARE #Wide smallint
DECLARE #More smallint
DECLARE #DBAI varchar(2000)
DECLARE #DBAO varchar(8000)
DECLARE #DBAU varchar(max)
DECLARE #Fuse int
DECLARE #File int
DECLARE #HeaderString varchar(8000)
DECLARE #HeaderDone int
SET #DBAE = '##SaveFile' + RIGHT(CONVERT(varchar(10),##SPID+100000),5)
SET #Task = 'IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = ' + CHAR(39) + #DBAE + CHAR(39) + ') DROP TABLE ' + #DBAE
EXECUTE (#Task)
SET #Bank = #TPre + #DBFetch
IF NOT EXISTS (SELECT * FROM sysobjects WHERE RTRIM(type) = 'U' AND name = #Bank)
BEGIN
SET #Bank = CASE WHEN LEFT(LTRIM(#DBFetch),6) = 'SELECT' THEN '(' + #DBFetch + ')' ELSE #DBFetch END
SET #Bank = REPLACE(#Bank, CHAR(94),CHAR(39))
SET #Bank = REPLACE(#Bank,CHAR(45)+CHAR(45),CHAR(32))
SET #Bank = REPLACE(#Bank,CHAR(47)+CHAR(42),CHAR(32))
END
IF #DBWhere IS NOT NULL
BEGIN
SET #Cash = REPLACE(#DBWhere,'WHERE' ,CHAR(32))
SET #Cash = REPLACE(#Cash, CHAR(94),CHAR(39))
SET #Cash = REPLACE(#Cash,CHAR(45)+CHAR(45),CHAR(32))
SET #Cash = REPLACE(#Cash,CHAR(47)+CHAR(42),CHAR(32))
END
IF #DBThere IS NOT NULL
BEGIN
SET #Risk = REPLACE(#DBThere,'ORDER BY' ,CHAR(32))
SET #Risk = REPLACE(#Risk, CHAR(94),CHAR(39))
SET #Risk = REPLACE(#Risk,CHAR(45)+CHAR(45),CHAR(32))
SET #Risk = REPLACE(#Risk,CHAR(47)+CHAR(42),CHAR(32))
END
SET #DBAI = ''
SET #DBAO = ''
SET #DBAU = ''
SET #Task = 'SELECT * INTO ' + #DBAE + ' FROM ' + #Bank + ' AS T WHERE 0 = 1'
IF #Status = 0 EXECUTE (#Task) SET #Return = ##ERROR
IF #Status = 0 SET #Status = #Return
-- For all columns (Fields) in the table.
DECLARE Fields CURSOR FAST_FORWARD FOR
SELECT '['+C.name+']', C.colid, T.name, C.isnullable, C.iscomputed, C.length, C.prec, C.scale
FROM tempdb.dbo.sysobjects AS O
JOIN tempdb.dbo.syscolumns AS C
ON O.id = C.id
JOIN tempdb.dbo.systypes AS T
ON C.xusertype = T.xusertype
WHERE O.name = #DBAE
ORDER BY C.colid
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
OPEN Fields
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
FETCH NEXT FROM Fields INTO #Same, #Rank, #Kind, #Mask, #Bond, #Size, #Wide, #More
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
-- Convert to character for header.
SET #HeaderString = ''
DECLARE #sql nvarchar(4000)
DECLARE #cDelimiter nvarchar(9)
DECLARE #cTextQuote nvarchar(9)
DECLARE #TypeFound bit
SET #sql = N'select #cDelimiter = ' + #Delimiter
EXEC sp_executesql #sql, N'#cDelimiter varchar(9) output', #cDelimiter output
SET #sql = N'select #cTextQuote = ' + #TextQuote
EXEC sp_executesql #sql, N'#cTextQuote varchar(9) output', #cTextQuote output
WHILE ##FETCH_STATUS = 0 AND #Status = 0
BEGIN
SET #TypeFound = 0
-- Build header.
IF LEN(#HeaderString) > 0 SET #HeaderString = #HeaderString + #cDelimiter + ISNULL(#cTextQuote + REPLACE(#Same, #cTextQuote, REPLICATE(#cTextQuote, 2))+#cTextQuote, SPACE(0))
IF LEN(#HeaderString) = 0 SET #HeaderString = ISNULL(#cTextQuote + REPLACE(#Same, #cTextQuote, REPLICATE(#cTextQuote, 2))+#cTextQuote, SPACE(0))
IF #Kind IN ('char','nchar','varchar','nvarchar','text','ntext','sysname','xml')
BEGIN
IF #NullQuoted = 0
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+REPLACE(' + #Same + ','+#TextQuote+',REPLICATE('+#TextQuote+',2))+'+#TextQuote+',SPACE(0))'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+REPLACE(' + #Same + ','+#TextQuote+',REPLICATE('+#TextQuote+',2))+'+#TextQuote+',SPACE(0))'
END
IF #NullQuoted = 1
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+REPLACE(' + #Same + ','+#TextQuote+',REPLICATE('+#TextQuote+',2))+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+REPLACE(' + #Same + ','+#TextQuote+',REPLICATE('+#TextQuote+',2))+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
END
SET #TypeFound = 1
END
IF #Kind IN ('bit','tinyint','smallint','int','bigint')
BEGIN
IF #NullQuoted = 0
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL(CONVERT(varchar(128),' + #Same + '),SPACE(0))'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL(CONVERT(varchar(128),' + #Same + '),SPACE(0))'
END
IF #NullQuoted = 1
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL(CONVERT(varchar(128),' + #Same + '),'+#TextQuote+'+'+#TextQuote+')'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL(CONVERT(varchar(128),' + #Same + '),'+#TextQuote+'+'+#TextQuote+')'
END
SET #TypeFound = 1
END
IF #Kind IN ('numeric','decimal','money','smallmoney','float','real')
BEGIN
IF #NullQuoted = 0
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL(CONVERT(varchar(128),' + #Same + '),SPACE(0))'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL(CONVERT(varchar(128),' + #Same + '),SPACE(0))'
END
IF #NullQuoted = 1
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL(CONVERT(varchar(128),' + #Same + '),'+#TextQuote+'+'+#TextQuote+')'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL(CONVERT(varchar(128),' + #Same + '),'+#TextQuote+'+'+#TextQuote+')'
END
SET #TypeFound = 1
END
IF #Kind IN ('uniqueidentifier','geometry','geography')
BEGIN
IF #NullQuoted = 0
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ')+'+#TextQuote+',SPACE(0))'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ')+'+#TextQuote+',SPACE(0))'
END
IF #NullQuoted = 1
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ')+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ')+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
END
SET #TypeFound = 1
END
IF #Kind IN ('datetime2','datetime','smalldatetime','time','date','datetimeoffset')
BEGIN
IF #NullQuoted = 0
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ','+convert(varchar(3),#DateTimeStyle)+')+'+#TextQuote+',SPACE(0))'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ','+convert(varchar(3),#DateTimeStyle)+')+'+#TextQuote+',SPACE(0))'
END
IF #NullQuoted = 1
BEGIN
IF #Rank = 1 SET #DBAU = ' ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ','+convert(varchar(3),#DateTimeStyle)+')+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
IF #Rank > 1 SET #DBAU = #DBAU + '+' + #Delimiter + '+ISNULL('+#TextQuote+'+CONVERT(varchar(128),' + #Same + ','+convert(varchar(3),#DateTimeStyle)+')+'+#TextQuote+','+#TextQuote+'+'+#TextQuote+')'
END
SET #TypeFound = 1
END
IF #TypeFound = 0
BEGIN
SET #Retain = 'ERROR: Data type ' + UPPER(#Kind) + ' was used but not supported by SaveDelimitedColumns.'
SET #Status = #Retain
END
FETCH NEXT FROM Fields INTO #Same, #Rank, #Kind, #Mask, #Bond, #Size, #Wide, #More
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
END
CLOSE Fields DEALLOCATE Fields
IF LEN(#DBAU) = 0 SET #DBAU = '*'
IF #PCWrite IS NOT NULL AND (#DBUltra = 0) AND (#Header = 1)
BEGIN
SET #HeaderString = replace(#HeaderString, '"', '""')
SET #DBAI = ' SELECT ' + CHAR(39) + #HeaderString + CHAR(39) + ' UNION ALL SELECT '
END
ELSE
SET #DBAI = ' SELECT '
SET #DBAO = ' FROM ' + #Bank + ' AS T'
+ CASE WHEN #DBWhere IS NULL THEN '' ELSE ' WHERE (' + #Cash + ') AND 0 = 0' END
+ CASE WHEN #DBThere IS NULL THEN '' ELSE ' ORDER BY ' + #Risk END
-- Output where #DBUltra = 0 (Uses XP_CMDSHELL \ BCP)
IF #PCWrite IS NOT NULL AND #DBUltra = 0
BEGIN
SET #Wish = 'USE ' + DB_NAME() + #DBAI + #DBAU + #DBAO
SET #Work = 'BCP "' + #Wish + '" QUERYOUT "' + #PCWrite + '" -w -T -S "' + ##SERVERNAME + '" '
-- PRINT #Work
EXECUTE #Return = master.dbo.xp_cmdshell #Work, NO_OUTPUT
SET #Retain = ##ERROR
IF #Status = 0 SET #Status = #Retain
IF #Status = 0 SET #Status = #Return
IF #Status <> 0 GOTO ABORT
END
-- Output where #DBUltra = 1 (Uses Ole Automation)
IF #PCWrite IS NOT NULL AND #DBUltra = 1
BEGIN
IF #Status = 0 EXECUTE #Return = sp_OACreate 'Scripting.FileSystemObject', #Fuse OUTPUT
SET #Retain = ##ERROR
IF #Status = 0 SET #Status = #Retain
IF #Status = 0 SET #Status = #Return
IF #Status = 0 EXECUTE #Return = sp_OAMethod #Fuse, 'CreateTextFile', #File OUTPUT, #PCWrite, -1
SET #Retain = ##ERROR
IF #Status = 0 SET #Status = #Retain
IF #Status = 0 SET #Status = #Return
IF #Status <> 0 GOTO ABORT
END
SET #DBAI = 'DECLARE Records CURSOR GLOBAL FAST_FORWARD FOR' + #DBAI
IF #Status = 0 EXECUTE (#DBAI+#DBAU+#DBAO) SET #Return = ##ERROR
IF #Status = 0 SET #Status = #Return
OPEN Records
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
FETCH NEXT FROM Records INTO #Next
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
-- Header.
SET #HeaderDone = 0
WHILE ##FETCH_STATUS = 0 AND #Status = 0
BEGIN
IF #PCWrite IS NOT NULL AND #DBUltra = 1
BEGIN
-- Write header (FILE).
IF (#Header = 1) and (#HeaderDone = 0)
BEGIN
SET #Save = #HeaderString + CHAR(13) + CHAR(10)
IF #Status = 0 EXECUTE #Return = sp_OAMethod #File, 'Write', NULL, #Save
SET #HeaderDone = 1
END
-- Write the data (FILE).
SET #Save = #Next + CHAR(13) + CHAR(10)
IF #Status = 0 EXECUTE #Return = sp_OAMethod #File, 'Write', NULL, #Save
IF #Status = 0 SET #Status = #Return
END
IF #PCWrite IS NULL
BEGIN
-- Print header (TEXT).
IF (#Header = 1) and (#HeaderDone = 0)
BEGIN
PRINT #HeaderString + CHAR(13) + CHAR(10)
SET #HeaderDone = 1
END
PRINT #Next
END
FETCH NEXT FROM Records INTO #Next
SET #Retain = ##ERROR IF #Status = 0 SET #Status = #Retain
END
CLOSE Records DEALLOCATE Records
-- Close output file (Ole Automation)
IF #PCWrite IS NOT NULL AND #DBUltra = 1
BEGIN
EXECUTE #Return = sp_OAMethod #File, 'Close', NULL
IF #Status = 0 SET #Status = #Return
EXECUTE #Return = sp_OADestroy #File
IF #Status = 0 SET #Status = #Return
EXECUTE #Return = sp_OADestroy #Fuse
IF #Status = 0 SET #Status = #Return
END
ABORT: -- This label is referenced when OLE automation fails.
IF #Status = 1 OR #Status NOT BETWEEN 0 AND 50000 RAISERROR ('SaveDelimitedColumns Windows Error [%d]', 16, 1, #Status)
SET #Task = 'IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = ' + CHAR(39) + #DBAE + CHAR(39) + ') DROP TABLE ' + #DBAE
EXECUTE (#Task);
RETURN (#Status);
END;
Add the lines
SET #HeaderString = replace(#HeaderString, '[', '')
SET #HeaderString = replace(#HeaderString, ']', '')
right after the line
CLOSE Fields DEALLOCATE Fields
SELECT '['+C.name+']', C.colid, T.name, C.isnullable, C.iscomputed, C.length, C.prec, C.scale
Right there you added the [ ] to your column names, C.Name is the column name. Most times you can get away with not using the braces, unless your tables use reserved words for column names.
SELECT C.name, C.colid, T.name, C.isnullable, C.iscomputed, C.length, C.prec, C.scale
Alternatively you could trim them at the end, right after you CLOSE and DEALOCATE your Fields cursor, like this:
CLOSE Fields DEALLOCATE Fields
SET #HeaderString = replace(replace(#HeaderString, ']', ''), '[', '')
Related
Generate script with INSERT SELECT statements from T-SQL
I have two databases in SQL Server 2014 Express, since a few days ago I am unifying both databases in such a way that there is only one left. When I have this new database I must pass it to Azure (I don't have any experience using this technology), however, I am doing tests on my local server, so far I have created the whole scheme but I must fill out all the tables to perform tests with my application. There are 313 tables of which many have more than 200,000 records, my question is, what is the best way to populate the database? Because at this moment I want to test my local machine, I could fill in the tables through Tasks> Generate Script> Advanced Options (Include only data) but this information will change the day when the migration to Azure is done, therefore I must Do the same process. So, is it possible to create an INSERT SELECT script so that it does not include records one by one and is as dynamic as possible? For example, you would have to generate an INSERT INTO similar to this: SET IDENTITY_INSERT [SchemaX].[TableA] ON ; INSERT INTO [SchemaX].[TableA] ( [id] ,[fieldA] ,[fieldB] ,[fieldC]) SELECT [id] ,[fieldA] ,[fieldB] ,[fieldC] FROM [server].[dbname].[SchemaX].[TableA] SET IDENTITY_INSERT [SchemaX].[TableA] OFF ; Some tables have IDENTITY enabled so you would have to recognize which tables are like this and use SET IDENTITY_INSERT when inserting. This way you would have to link the production server and insert the information into the local server. If there are suggestions or recommendations about another way you are welcome
Has been answered before ... /****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[procUtils_GenerateInsertProc]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[procUtils_GenerateInsertProc] GO /****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --exec procUtils_GenerateInsertProc 'Whatever' --exec sp_HelpText procUtils_GenerateInsertProc CREATE PROCEDURE [dbo].[procUtils_GenerateInsertProc] #TableName [varchar](50) WITH EXECUTE AS CALLER AS BEGIN -- proc start SET NOCOUNT ON; BEGIN TRY --begin try --FIRST SEARCH THE TABLE WHICH HAD A "Feature" in its name --SELECT NAME FROM SYS.TABLES WHERE NAME LIKE '%Feature%' --SELECT column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Feature' --SELECT * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Task' --Decalre a variable to remember the position of the current delimiter DECLARE #ProcName varchar(1000) set #ProcName = '[dbo].[procGen_' + #TableName + '_Insert]' DECLARE #CurrentDelimiterPositionVar INT DECLARE #PkColumnName varchar(200) --Decalre a variable to remember the number of rows in the table DECLARE #Count INT DECLARE #ColumnName varchar(300); DECLARE #DataType varchar(50) DECLARE #IsNullable bit DECLARE #MaxLength INT DECLARE #IsComputed BIT set #IsComputed = 0 DECLARE #IsPrimaryKey BIT set #IsPrimaryKey = 0 DECLARE #CODESTR VARCHAR(max) --PRINT DROP PROCEDURE set #CODESTR = ' ' --Declare the Table variable DECLARE #ColumnNames TABLE ( Number INT IDENTITY(1,1), --Auto incrementing Identity column TableName varchar(300) , --the name of the table ColumnName VARCHAR(300) , --The string value , DataType varchar(50) , --the datatype IsNullable bit , --should we add =null in front MaxLength INT , --VARCHAR(LENGHTi) IsComputed bit , --whether or not this table is computed IsPrimaryKey bit --whether or not this table is computed ) --Populate the TABLE variable using some logic -- SELECT * from INFORMATION_SCHEMA.COLUMNS INSERT INTO #ColumnNames ( TableName , ColumnName , DataType , IsNullable , MaxLength , IsComputed , IsPrimaryKey ) SELECT TableName , ColumnName , DataType , IsNullable , MaxLength , IsComputed , IsPrimaryKey from viewMeta_TableColumns --debug where TableName = 'Whatever' where TableName = #TableName --SELECT column_name , Data_type , IsNullable , MaxLength --from INFORMATION_SCHEMA.COLUMNS --where TABLE_NAME=#TableName --Initialize the looper variable SET #CurrentDelimiterPositionVar = 1 --Determine the number of rows in the Table SELECT #Count=max(Number) from #ColumnNames --A variable to hold the currently selected value from the table set #CODESTR = #CODESTR + 'IF OBJECT_ID(''' + #ProcName + ''') IS NOT NULL BEGIN DROP PROC ' + #ProcName + ' END GO' set #CODESTR = #CODESTR + ' /****** Object: StoredProcedure ' + #ProcName + '*/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE ' + #ProcName + ' #CurUserSessionId [int] , #CurPageTypeId [int] , #MsgOut [varchar](200) OUTPUT , #DebugMsgOut [varchar](200) OUTPUT, #Ret [int] OUTPUT ,' + CHAR(13) --#COLUMN_NAME [DATA_TYPE] (MAX_LENGTH) =NULL , WHILE #CurrentDelimiterPositionVar <= #Count --1st loop BEGIN --Load current value from the Table SELECT #ColumnName = ColumnName FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #DataType = DataType FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #MaxLength = MaxLength FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar set #IsNullable = ( select IsNullable FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) if ( #DataType = 'timestamp' or #IsComputed = 1) begin set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1 continue end set #CODESTR = #CODESTR + '#' + #ColumnName + ' ['+ #DataType + '] ' --ADD THE (200) IF #MaxLength IS NOT NULL BEGIN --IF #MaxLength IS NOT NULL --xml if #DataType <> 'xml' and #DataType <> 'sql_variant' and #DataType <> 'text' and #DataType <> 'ntext' and #DataType <> 'image' and #DataType <> 'hierarchyid' and #DataType <> 'bit' and #DataType <> 'varbinary' and #DataType <> 'int' and #DataType <> 'uniqueidentifier' and #DataType <> 'tinyint' and #DataType <> 'timestamp' and #DataType <> 'uniqueidentifier' and #DataType <> 'smallint' and #DataType <> 'bigint' and #DataType <> 'smallmoney' and #DataType <> 'money' and #DataType <> 'real' and #DataType <> 'smalldatetime' and #DataType <> 'datetime' begin --those with() if #MaxLength <> -1 SET #CODESTR = #CODESTR + '(' + CONVERT(VARCHAR , #MaxLength ) + ')' else SET #CODESTR = #CODESTR + '(max)' end --those with(200) else begin SET #CODESTR = #CODESTR --DO NOTHING end END --IF #MaxLength IS NOT NULL IF #IsNullable = 1 SET #CODESTR = + #CODESTR + ' = NULL ' if #IsPrimaryKey = 1 SET #CODESTR = #CODESTR + ' OUTPUT ' if #CurrentDelimiterPositionVar <> #Count SET #CODESTR = #CODESTR + ',' --DEBUGGING --set #CODESTR = #CODESTR + '#ColumnName - ' + #ColumnName --set #CODESTR = #CODESTR + '#DataType - ' + #DataType --set #CODESTR = #CODESTR + '#IsNullable - ' + #IsNullable --set #CODESTR = #CODESTR + '#MaxLength - ' + CONVERT ( VARCHAR , #MaxLength ) set #CODESTR = #CODESTR + CHAR(13) SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1 END SET #CODESTR = #CODESTR + ' WITH EXECUTE AS CALLER AS BEGIN -- proc start SET NOCOUNT ON; BEGIN TRY --begin try -- set #Ret = 1 --assume false from the beginning declare #MsgKey [nvarchar](max) declare #MsgTxt [nvarchar](max) exec procUtils_GetMsgTxtByKeyAndUserSessionId #UserSessionId =2 , #MsgKey = ''MsgOkTheAddingOfItemIsOk'' , #MsgTxt = '''' set #MsgOut = replace (#MsgTxt , ''{0}'' , ''' + #TableName + ''' ) declare #thisProcName varchar(300) set #thisProcName= ( SELECT OBJECT_NAME(##PROCID)) ' SET #CurrentDelimiterPositionVar = 1 --START LOOP AGAIN set #CODESTR = #CODESTR + ' --Action !!! INSERT INTO [dbo].[' + #TableName + ']( ' + CHAR(13) --Loop through until all row processing is done WHILE #CurrentDelimiterPositionVar <= #Count --2nd loop BEGIN --Load current value from the Table SELECT #ColumnName = ColumnName FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #DataType = DataType FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #MaxLength = MaxLength FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar set #IsNullable = ( select IsNullable FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) if #IsPrimaryKey = 1 begin -- the primary key set #PkColumnName = #ColumnName end --the primary key if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1 ) begin set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1 continue end --select if #CurrentDelimiterPositionVar <= #Count BEGIN set #CODESTR = #CODESTR + '[' + #ColumnName + ']' --null the codestring var if #CurrentDelimiterPositionVar <> #Count set #CODESTR = #CODESTR + ', --type of ' + #DataType + CHAR(13) --WITH COMMA ELSE set #CODESTR = #CODESTR + ' --type of ' + #DataType + CHAR(13) --NO COMMA END -- IF SHOULD PRINT COLUMN SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1; END --eof while 2 set #CODESTR = #CODESTR + ') VALUES ( ' --AND START ALL OVER AGAIN SET #CurrentDelimiterPositionVar = 1 --Loop through until all row processing is done WHILE #CurrentDelimiterPositionVar <= #Count --WHILE 3 BEGIN --Load current value from the Table SELECT #ColumnName = ColumnName FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #DataType = DataType FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar SELECT #MaxLength = MaxLength FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar set #IsNullable = ( select IsNullable FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames WHERE Number = #CurrentDelimiterPositionVar ) if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1) begin set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1 continue end set #CODESTR = #CODESTR + '#' + #ColumnName if #CurrentDelimiterPositionVar <= #Count BEGIN IF #CurrentDelimiterPositionVar <> #Count set #CODESTR = #CODESTR + ' , --type of ' + #DataType --all others with comma else set #CODESTR = #CODESTR + ' --type of ' + #DataType --the last one without comma END -- IF SHOULD NOT PRINT COLUMN --increase the counter set #CODESTR = #CODESTR + CHAR(13) SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1; END set nocount off SET #CODESTR = #CODESTR + ') SET #' + #pkColumnName + ' = ##IDENTITY set #Ret = ##ERROR set #DebugMsgOut = ''TODO:REMOVE INSERT OK '' END TRY BEGIN CATCH EXEC #ret = [dbo].[procUtils_GetMsgTxtByKeyAndUserSessionId] #UserSessionId = 2, #MsgKey = N''ErrorMsgMenuRetrievalFailed'', #MsgTxt = #MsgOut OUTPUT set #ret = 1 set #msgOut = #MsgTxt set #debugMsgOut = '' Error number: '' + CAST(ERROR_NUMBER() AS varchar(100)) + ''Error message: '' + ERROR_MESSAGE() + ''Error severity: '' + CAST(ERROR_SEVERITY() AS varchar(10)) + ''Error state: '' + CAST(ERROR_STATE() AS varchar(100)) + ''XACT_STATE: '' + CAST(XACT_STATE() AS varchar(100)) -- record the error in the database set #debugMsgOut = #debugMsgOut + #msgOut INSERT INTO [dbo].[LogStore] ( [Date],[Thread],[Level],[Logger],[Message]) values ( getdate() , N''8'', N''DEBUG'', #thisProcName , #debugMsgOut ) END CATCH END --procedure end GO ' print #codestr END TRY --end try BEGIN CATCH print ' Error number: ' + CAST(ERROR_NUMBER() AS varchar(100)) + 'Error message: ' + ERROR_MESSAGE() + 'Error severity: ' + CAST(ERROR_SEVERITY() AS varchar(1000)) + 'Error state: ' + CAST(ERROR_STATE() AS varchar(100)) + 'XACT_STATE: ' + CAST(XACT_STATE() AS varchar(100)) END CATCH END --procedure end --USE [Gaf] --GO --SELECT NAME FROM SYS.tables where name like '%Msg%' --EXEC [dbo].[procUtils_GenerateInsertProc] #TableName = N'Whatever' GO
Error Pass from nested MSSQL procedure to parent procedure
I have one parent stored procedure and one nested stored procedure. Parent Stored procedure calls the nested stored procedure on loop. Now when there is certain condition matches I have raised the error. When this error is raised I want to stop all the process and return the error. CREATE Proc [dbo].[Usp_GenSalarySheet](#SalData [HRM].UTDT_SalaryData ReadOnly) AS set nocount on DECLARE #SMT NVARCHAR(MAX) SET #SMT = 'Create Table ##SalarySheet (StaffID INT,FullName NVARCHAR(1024),PresentDays NVARCHAR(1024),Absent NVARCHAR(1024),Department NVARCHAR(1024),Designation NVARCHAR(1024),' DECLARE #HopName nvarchar(max) Declare HOPCursor cursor for select ID from HRM.tbl_HOP OPEN HOPCursor FETCH NEXT FROM HOPCursor INTO #HopName WHILE ##FETCH_STATUS = 0 BEGIN SET #SMT = #SMT + ' [' + #HopName + '] DECIMAL(19,7),' FETCH NEXT FROM HOPCursor into #HopName END SET #SMT = #SMT + '[Total] DECIMAL(19,7))' CLOSE HOPCursor DEALLOCATE HOPCursor print (#smt) exec (#SMT) select * into #temp from #SalData Declare #TopID INT While (Select Count(*) From #Temp) > 0 Begin Select Top 1 #TopID = StaffID From #temp Declare #StaffID INT =(select top 1 StaffID from #temp) Declare #StaffName NVARCHAR(1024) = (SELECT TOP 1 FullName FROM #temp) Declare #WorkingDays Int = (SELECT top 1 WorkingDays from #temp) Declare #Leave INT = (SELECT top 1 [Absent] from #temp) INSERT INTO ##SalarySheet(StaffID,FullName,[Absent]) values(#StaffID,#StaffName,#Leave) DECLARE #HOPType INT DECLARE #Value Decimal(19,7) DECLARE #CalcVal DECIMAL(19,7) = 0 DECLARE #Formula NVARCHAR(MAX) DECLARE #Total DECIMAL(19,7) DECLARE #PayEvery INT DECLARE #Round Int Declare HOPList Cursor for SELECT ID,HOPType,Value,Formula,RoundOff,PayEvery FROM HRM.Tbl_HOP order by Schedule open HOPList FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery WHILE ##FETCH_STATUS = 0 BEGIN if exists(select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = #StaffID and HOPID = #HopName) print('select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = ' + convert(varchar(max), #StaffID) + ' and HOPID =' + convert(varchar(max),#HopName)) begin if(#HOPType=51) begin exec HRM.Usp_GetSalaryValueFromFormula #StaffID,#Formula,#HOPType,#Leave,#WorkingDays,#Value output set #HOPType= 50 end if(#HOPType=50) begin set #CalcVal = #value END IF(#HOPType=38) BEGIN SET #CalcVal = #Value - ((#Value/#WorkingDays) * #Leave) END if(#PayEvery= 40) begin set #CalcVal = ((#CalcVal * #WorkingDays) - (#CalcVal * #Leave)) end if(#Round = 45) begin set #CalcVal = round(#CalcVal,2) end else if(#Round = 46) begin set #CalcVal = CEILING(#CalcVal) end else if(#Round = 47) begin set #CalcVal = FLOOR(#CalcVal) end set #SMT ='UPDATE ##SalarySheet SET [' + #HopName + '] = ' + cast(#CalcVal as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max)) exec (#smt) end SET #CalcVal = 0 FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery END close HOPList DEALLOCATE HOPList set #SMT ='UPDATE ##SalarySheet SET [Total] = ' + cast(#Total as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max)) exec (#smt) Delete #temp Where StaffID = #TopID end select * from ##SalarySheet drop table ##SalarySheet This is my parent Stored Procudere and nested procedure is as follow: CREATE proc [HRM].[Usp_GetSalaryValueFromFormula](#StaffID INT,#val nvarchar(max),#HOPType INT,#Leave INT,#WorkingDays INT, #GetResult Decimal(19,7) output) as set nocount on Declare #Formula Varchar(max) declare #initial INT =0 declare #final INT =0 Declare #DataVal NVARCHAR(MAX) -- set the value from HOP table declare #FieldVal nvarchar(max) declare #cnt int = 0 Declare #Complete Int =CHARINDEX ('[',#val,0) while (#Complete <> 0) begin set #initial = CHARINDEX ('[',#val,0) set #final = CHARINDEX(']',#val,0) set #FieldVal = SUBSTRING(#val,#initial,(#final-#initial) + 1) if len(#FieldVal)<>0 begin select #HOPType = HOPType, #DataVal= ( case when HOPType = 51 then [Formula] else cast([Value] as nvarchar(max)) end) from HRM.Tbl_ContractHOPDetails where PersonalDetailsID = #StaffID and HOPID in(select ID from HRM.tbl_HOP where HOPName = replace(replace(#fieldVal,'[',''),']','')) if (#DataVal is null or #DataVal ='') begin RAISERROR ('Nested HOP is not defined.',11,1) RETURN end print(#DataVal) if ISNUMERIC(#DataVal)=1 begin if(#HOPType = 38) begin SET #DataVal = cast(#DataVal as decimal(19,7)) - ((cast(#DataVal as decimal(19,7))/#WorkingDays) * #Leave) end end set #val = replace(#val,#fieldVal,#DataVal) set #fieldVal= '' set #DataVal = '' end set #Complete = CHARINDEX ('[',#val,0) set #fieldVal ='' set #final =0 set #initial = 0 end SET #Complete =CHARINDEX ('{',#val,0) while (#Complete <> 0) BEGIN set #initial = CHARINDEX ('{',#val,0) set #final = CHARINDEX('}',#val,0) set #FieldVal = SUBSTRING(#val,#initial+1,(#final-#initial)-1) if len(#FieldVal)<>0 begin set #DataVal = isnumeric((SELECT 0 FROM [HRM].Tbl_StaffTag where CValue = #FieldVal and StaffID = #StaffID)) set #FieldVal = '{' + #FieldVal + '}' set #val = replace(#val,#fieldVal,#DataVal) set #fieldVal= '' set #DataVal = '' end set #Complete = CHARINDEX ('{',#val,0) set #final =0 set #initial = 0 END DECLARE #RetrunVal DECIMAL(19,7) declare #ParmDefinition Nvarchar(512) = '#GetVal decimal(19,7) OUTPUT' Declare #SMT NVARCHAR(MAX) = ' SET #GetVal = ' + #val EXECUTE sp_executeSQL #Smt, #ParmDefinition, #GetVal =#RetrunVal OUTPUT set #GetResult = #RetrunVal But in current situation it raises error and again from the main procedure it runs next step of loop. But I want to terminate the complete process after this raiserror Kindly help me
My guess is that RaiseError throws the control back to the caller, which might make the Return statement unreachable. The caller (loop) continues with next iteration.
sp_sqlexec - To many arguments specified
I get the error 'Too many arguments specified' but cannot find the problem Any help would be greatly appreciated The 3 parameters are specified at the begin of the procedure DECLARE #WhereStatment nvarchar(500), #ParamList nvarchar(500) = N'#p1 int, #p2 varchar(256), #p3 int' SET #WhereStatment = '' -- Check for Status Filter IF #StatusFilter <> 'All' SET #WhereStatment = #WhereStatment + ' EntryStatus = #StatusFilter' ELSE BEGIN SET #StatusFilter = 'Invoiced (Complete)' SET #WhereStatment = #WhereStatment + ' EntryStatus <> #StatusFilter' END -- Check for User Filter IF #UserFilter > 0 SET #WhereStatment = #WhereStatment + ' AND EobID = #UserFilter' -- Check for Warehouse Filter IF #WarehouseFilter > 0 SET #WhereStatment = #WhereStatment + ' AND WarehouseNumber = #WarehouseFilter' -- Add WhereStatement Set #WhereStatment = ' SELECT tblWCS_SQE_Entries.RowID, SaleNum, tblWCS_Company_UserAccounts.Fullname, Ets FROM tblWCS_SQE_Entries INNER JOIN tblWCS_Company_UserAccounts ON tblWCS_SQE_Entries.EobID = tblWCS_Company_UserAccounts.RowID WHERE ' + #WhereStatment; EXEC sp_sqlexec #WhereStatment, #ParamList, #p1 = #UserFilter, #p2 = #StatusFilter, #p3 = #WarehouseFilter
sp_sqlexec stored procedure indeed has only one parameter. Probably you want sp_executesql instead.
DECLARE #SQL NVARCHAR(MAX) SET #SQL = ' SELECT tblWCS_SQE_Entries.RowID, SaleNum, tblWCS_Company_UserAccounts.Fullname, Ets FROM dbo.tblWCS_SQE_Entries JOIN dbo.tblWCS_Company_UserAccounts ON tblWCS_SQE_Entries.EobID = tblWCS_Company_UserAccounts.RowID WHERE ' + CASE WHEN #StatusFilter = 'All' THEN ' EntryStatus <> ''Invoiced (Complete)''' ELSE ' EntryStatus = #StatusFilter' END + CASE WHEN #WarehouseFilter > 0 THEN ' AND WarehouseNumber = #WarehouseFilter' ELSE '' END + CASE WHEN #UserFilter > 0 THEN ' AND EobID = #UserFilter' ELSE '' END EXEC sys.sp_executesql #SQL , N'#p1 int, #p2 varchar(256), #p3 int' , #p1 = #UserFilter , #p2 = #StatusFilter , #p3 = #WarehouseFilter
Invalid Column Name '#FileName-- value'
I am getting 'Invalid Column Name '#FileName-- value'' ERROR WHILE executing below stored procedure. I tried to find the root cause of the issue with no luck...Please suggest me where i am wrong. ALTER PROCEDURE [dbo].[usp_ICLExtract_GetFile] #FileName Varchar(50), #Image_Path Varchar(50) Output, #FIleNameList varchar(4096) OUTPUT AS BEGIN SET NOCOUNT ON DECLARE #strProcName varchar(255) SET #strProcName = 'usp_ICLExtract_GetFile' DECLARE #strSQL1 varchar(1024), #strSQL2 varchar(1024) DECLARE #strFileName Varchar(50) DECLARE #intErrorReturn int SET #intErrorReturn = 0 SET #FileNameList = '' SET #Image_Path = '' SET #strSQL1 = N'SELECT tbl_ICLExtCashLetter.Image_Path from tbl_ICLExtCashLetter INNER JOIN tbl_ICLExtFile on [tbl_ICLExtCashLetter].ICLExtFileUID = [tbl_ICLExtFile].ICLExtFileUID where tbl_ICLExtFile.FileName = ' + #FileName --This line cause error /*============================================================================== * Run the query' *==============================================================================*/ SET #strSQL2 = 'DECLARE curCategory INSENSITIVE SCROLL CURSOR FOR ' + #strSQL1 EXEC(#strSQL2) SELECT #intErrorReturn = ##ERROR IF (#intErrorReturn <> 0) GOTO usp_ICLExtract_GetFile_Error OPEN curCategory SELECT #intErrorReturn = ##ERROR IF (#intErrorReturn <> 0) GOTO usp_ICLExtract_GetFile_Error FETCH NEXT FROM curCategory INTO #strFileName WHILE (##FETCH_STATUS <> -1) BEGIN SET #FileNameList = #FileNameList + #strFileName + ';' SET #Image_Path = #Image_Path + 1 FETCH NEXT FROM curCategory INTO #strFileName END CLOSE curCategory DEALLOCATE curCategory RETURN(0) usp_ICLExtract_GetFile_Error: RETURN(#intErrorReturn) END
replace line with this SET #strSQL1 = N'SELECT tbl_ICLExtCashLetter.Image_Path from tbl_ICLExtCashLetter INNER JOIN tbl_ICLExtFile on [tbl_ICLExtCashLetter].ICLExtFileUID = [tbl_ICLExtFile].ICLExtFileUID where tbl_ICLExtFile.FileName = ''' + #FileName +'''
Change your query to this: N'SELECT tbl_ICLExtCashLetter.Image_Path from tbl_ICLExtCashLetter INNER JOIN tbl_ICLExtFile on [tbl_ICLExtCashLetter].ICLExtFileUID = [tbl_ICLExtFile].ICLExtFileUID where tbl_ICLExtFile.FileName = ''' + #FileName + '''' you have to pass value between apostrophes '.
SQL Server stored procedure
I want it to count then if #intcount > 0 it should show data or else no data found, but when I execute it gives me 'no data found' regardless, what am I doing wrong? #FiscalYear int, #SchoolID int, #Status int AS BEGIN SET NOCOUNT ON; declare #sqlstr varchar(2000) declare #intCount int set #intCount = 0 set #sqlstr = 'Select #intCount = Count(*) From PrivateSchool left outer join Attachment on Attachment.PrivateSchoolID = PrivateSchool.PrivateSchoolID inner join FiscalYearPrivateSchool fp ON fp.PrivateSchoolID = PrivateSchool.PrivateSchoolID Where (FiscalYear = '+convert(varchar, #FiscalYear)+') AND (PrivateSchool.IsActive = 1)' IF (#SchoolID != -1) SET #sqlstr = #sqlstr + ' AND SchoolID ='+ convert(varchar, #SchoolID) IF (#Status = -1) SET #sqlstr = #sqlstr + ' AND PrivateSchool.PrivateSchoolID = PrivateSchool.PrivateSchoolID' Else IF (#Status = 1) SET #sqlstr = #sqlstr + ' AND Attachment.PrivateSchoolID = PrivateSchool.PrivateSchoolID' Else SET #sqlstr = #sqlstr + ' AND Attachment.PrivateSchoolID is Null' If (#intCount > 0) BEGIN set #sqlstr= 'Select SchoolName as School, (Case when Attachment.PrivateSchoolID = PrivateSchool.PrivateSchoolID THEN ''Uploaded'' ELSE ''Not Uploaded'' END) AS Status, COUNT(Attachment.PrivateSchoolID) AS [Count] From PrivateSchool left outer join Attachment on Attachment.PrivateSchoolID = PrivateSchool.PrivateSchoolID inner join FiscalYearPrivateSchool fp ON fp.PrivateSchoolID = PrivateSchool.PrivateSchoolID Where (FiscalYear = '+convert(varchar, #FiscalYear)+') AND (PrivateSchool.IsActive = 1)' IF (#SchoolID != -1) SET #sqlstr = #sqlstr + ' AND SchoolID ='+ convert(varchar, #SchoolID) IF (#Status = -1) SET #sqlstr = #sqlstr + ' AND PrivateSchool.PrivateSchoolID = PrivateSchool.PrivateSchoolID' Else IF (#Status = 1) SET #sqlstr = #sqlstr + ' AND Attachment.PrivateSchoolID = PrivateSchool.PrivateSchoolID' Else SET #sqlstr = #sqlstr + ' AND Attachment.PrivateSchoolID is Null' SET #sqlstr = #sqlstr + ' Group by SchoolName, Attachment.PrivateSchoolID, PrivateSchool.PrivateSchoolID' SET #sqlstr = #sqlstr + ' Order By SchoolName' EXEC(#sqlstr) END ELSE Select 'No Data Found' as 'FileUpload' END
You need: EXEC sp_executesql #sqlstr, N'#intCount INT OUTPUT', #intCount = #intCount OUTPUT; IF (#intCount > 0) BEGIN .... END You'll also need to make #sqlstr NVARCHAR(2000) and add set it to N'SELECT ...' as opposed to 'SELECT ...' - that leading N can be important.
The problem is: declare #intCount int set #intCount = 0 ... <a bunch of code where #intcount doesn't change> If (#intCount > 0) It's always going to be 0.
Your issue is one of scope. The EXEC(#sqlstr) command doesn't have access to the #intcount variable in your stored procedure. I would bet if you ran this code in a query window, it would tell you to declare #intcount. Listen to YUCK and rewrite this to avoid dynamic SQL, and then your SELECT will be able to set the #intcount variable.