Related
I have a dynamic query that adds WHERE clauses according to the parameters received:
DECLARE #p1 varchar(max);
DECLARE #p2 varchar(max);
DECLARE #p3 varchar(max);
DECLARE #p4 varchar(max);
DECLARE #p5 varchar(max);
DECLARE #p6 varchar(max);
DECLARE #p7 varchar(max);
DECLARE #p8 varchar(max);
DECLARE #p9 varchar(max);
DECLARE #p10 varchar(max);
DECLARE #p11 varchar(max);
DECLARE #p12 varchar(max);
SET #p9 = 'Acta'
DECLARE #SQL varchar(max);
SET #SQL =
'SELECT
COUNT(*) AS [regs]
FROM [dbo].[DP_Fichas] [F]
WHERE 1 = 1';
IF(#p1 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[ID] = ''' + #p1 + ''''
END;
IF(#p2 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Titulo] LIKE ''%' + #p2 + '%'''
END;
IF(#p3 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Texto] = ''' + #p3 + ''''
END;
IF(#p4 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Fecha] = ''' + #p4 + ' 00:00:00.0000000'''
END;
IF(#p5 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Constitucionailidad] = ''' + #p5 + ''''
END;
IF(#p6 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Comentarios] = ''' + #p6 + ''''
END;
IF(#p7 IS NOT NULL)
BEGIN
DECLARE #idfuente varchar(max)
SET #idfuente =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Fuentes] [X1]
WHERE
([X1].[Nombre] = #p7)
)
SET #SQL = #SQL + '
AND [F].[IdFuente] = ''' + #idfuente + ''''
END;
IF(#p8 IS NOT NULL)
BEGIN
DECLARE #idvigencia varchar(max)
SET #idvigencia =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Vigencia] [X1]
WHERE
([X1].[Nombre] = #p8)
)
SET #SQL = #SQL + '
AND [F].[IdVigencia] = ''' + #idvigencia + ''''
END;
IF(#p9 IS NOT NULL)
BEGIN
DECLARE #idtipo varchar(max)
SET #idtipo =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_TipoFicha] [X1]
WHERE
([X1].[Nombre] = #p9)
)
SET #SQL = #SQL + '
AND [F].[IdIdentificacion] = ''' + #idtipo + ''''
END;
IF(#p10 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[NormaNumero] = ''' + #p10 + ''''
END;
IF(#p11 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Publicacion] = ''' + #p11 + ''''
END;
IF(#p12 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[TemaResumen] = ''' + #p12 + ''''
END;
EXEC(#SQL);
In this example, only the #p9 parameter has a value, so the returned SQL command will be:
SELECT COUNT(*) AS [regs]
FROM [dbo].[DP_Fichas] [F]
WHERE 1 = 1
AND [F].[IdIdentificacion] = '2'
This is working just fine when I execute the query, but when I save it to a stored procedure, it comes back empty.
This is the code for the stored procedure:
CREATE PROCEDURE [dbo].[SEL_DP_Fichas_Buscar_Algoritmo_Contar]
(
#p1 varchar(max),
#p2 varchar(max),
#p3 varchar(max),
#p4 varchar(max),
#p5 varchar(max),
#p6 varchar(max),
#p7 varchar(max),
#p8 varchar(max),
#p9 varchar(max),
#p10 varchar(max),
#p11 varchar(max),
#p12 varchar(max)
)
AS
BEGIN
DECLARE #p1f varchar(max) = #p1;
DECLARE #p2f varchar(max) = #p2;
DECLARE #p3f varchar(max) = #p3;
DECLARE #p4f varchar(max) = #p4;
DECLARE #p5f varchar(max) = #p5;
DECLARE #p6f varchar(max) = #p6;
DECLARE #p7f varchar(max) = #p7;
DECLARE #p8f varchar(max) = #p8;
DECLARE #p9f varchar(max) = #p9;
DECLARE #p10f varchar(max) = #p10;
DECLARE #p11f varchar(max) = #p11;
DECLARE #p12f varchar(max) = #p12;
DECLARE #SQL varchar(max);
SET #SQL =
'SELECT
COUNT(*)
FROM [dbo].[DP_Fichas] [F]
WHERE 1 = 1'
IF(#p1 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[ID] = ''' + #p1 + ''''
END;
IF(#p2 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Titulo] LIKE ''%' + #p2 + '%'''
END;
IF(#p3 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Texto] = ''' + #p3 + ''''
END;
IF(#p4 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Fecha] = ''' + #p4 + ' 00:00:00.0000000'''
END;
IF(#p5 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Constitucionailidad] = ''' + #p5 + ''''
END;
IF(#p6 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Comentarios] = ''' + #p6 + ''''
END;
IF(#p7 IS NOT NULL)
BEGIN
DECLARE #idfuente varchar(max)
SET #idfuente =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Fuentes] [X1]
WHERE
([X1].[Nombre] = #p7)
)
SET #SQL = #SQL + '
AND [F].[IdFuente] = ''' + #idfuente + ''''
END;
IF(#p8 IS NOT NULL)
BEGIN
DECLARE #idvigencia varchar(max)
SET #idvigencia =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Vigencia] [X1]
WHERE
([X1].[Nombre] = #p8)
)
SET #SQL = #SQL + '
AND [F].[IdVigencia] = ''' + #idvigencia + ''''
END;
IF(#p9 IS NOT NULL)
BEGIN
DECLARE #idtipo varchar(max)
SET #idtipo =
(
SELECT
[X1].[ID]
FROM [dbo].[DP_TipoFicha] [X1]
WHERE
([X1].[Nombre] = #p9)
)
SET #SQL = #SQL + '
AND [F].[IdIdentificacion] = ''' + #idtipo + ''''
END;
IF(#p10 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[NormaNumero] = ''' + #p10 + ''''
END;
IF(#p11 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[Publicacion] = ''' + #p11 + ''''
END;
IF(#p12 IS NOT NULL)
BEGIN
SET #SQL = #SQL + '
AND [F].[TemaResumen] = ''' + #p12 + ''''
END;
EXECUTE (#SQL);
END
GO
Whenever I run the stored procedure:
EXEC [dbo].[SEL_DP_Fichas_Buscar_Algoritmo_Contar]
#p1 = '',
#p2 = '',
#p3 = '',
#p4 = '',
#p5 = '',
#p6 = '',
#p7 = '',
#p8 = '',
#p9 = 'Actas',
#p10 = '',
#p11 = '',
#p12 = '';
I should get 142 as a count result, but I'm getting:
Commands completed successfully.
Completion time: 2021-06-15T16:36:31.1131407-05:00
I need this stored procedure to fill up a GridView:
string spQuerySel0 = "SEL_DP_Fichas_Buscar_Algoritmo";
DataSet dsFlt1;
SqlConnection conFlt1;
SqlDataAdapter daFlt1;
conFlt1 = new SqlConnection(enchufe);
daFlt1 = new SqlDataAdapter(spQuerySel0, conFlt1);
daFlt1.SelectCommand.CommandType = CommandType.StoredProcedure;
daFlt1.SelectCommand.Parameters.AddWithValue("#p1", p1);
daFlt1.SelectCommand.Parameters.AddWithValue("#p2", p2);
daFlt1.SelectCommand.Parameters.AddWithValue("#p3", p3);
daFlt1.SelectCommand.Parameters.AddWithValue("#p4", p4);
daFlt1.SelectCommand.Parameters.AddWithValue("#p5", p5);
daFlt1.SelectCommand.Parameters.AddWithValue("#p6", p6);
daFlt1.SelectCommand.Parameters.AddWithValue("#p7", p7);
daFlt1.SelectCommand.Parameters.AddWithValue("#p8", p8);
daFlt1.SelectCommand.Parameters.AddWithValue("#p9", p9);
daFlt1.SelectCommand.Parameters.AddWithValue("#p10", p10);
daFlt1.SelectCommand.Parameters.AddWithValue("#p11", p11);
daFlt1.SelectCommand.Parameters.AddWithValue("#p12", p12);
dsFlt1 = new DataSet();
daFlt1.Fill(dsFlt1, spQuerySel0);
gvFichasRes.DataSource = dsFlt1.Tables[spQuerySel0].DefaultView;
gvFichasRes.DataBind();
daFlt1.Dispose();
conFlt1.Close();
But I'm getting a null exception, I guess that is because the stored procedure is returning nothing.
I've also tried to add OUTPUT to the query, but It'll break to a "Not found procedure" error.
What can I do here?
This type of query is known as a Kitchen-Sink query.
You have a number of issues with your current code:
#SQL should be declared as nvarchar(max)
You should parameterize the dynamic statement, in other words: the parameters should be pushed through via sp_executesql
The same applies to the subqueries, they can be run in the dynamic part
The parameter types should match the columns they are compared against, which in turn should be fitting for the data in them. I've made a guess at suitable types.
It's unclear what you hoped to achieve with the extra DECLARE #p1f statements, perhaps to avoid parameter sniffing, but that can be avoided with OPTION(OPTIMIZE FOR UNKNOWN), and in any case doing this dynamically means you probably should use parameter sniffing
In the C# side, you should dispose all SQL objects with using blocks
You should also avoid AddWithValue, specify the parameter types explicitly.
So your final procedure would look something like this:
CREATE PROCEDURE [dbo].[SEL_DP_Fichas_Buscar_Algoritmo_Contar]
(
#p1 int,
#p2 varchar(200),
#p3 varchar(200),
#p4 date,
#p5 char(2),
#p6 varchar(200),
#p7 int,
#p8 int,
#p9 int,
#p10 varchar(200),
#p11 varchar(200),
#p12 varchar(200)
)
AS
DECLARE #SQL nvarchar(max) =
N'
SELECT
COUNT(*)
FROM [dbo].[DP_Fichas] [F]
WHERE 1 = 1'
;
IF(#p1 IS NOT NULL)
SET #SQL += N'
AND [F].[ID] = #p1';
IF(#p2 IS NOT NULL)
SET #SQL += N'
AND [F].[Titulo] LIKE ''%'' + #p2 + ''%''';
IF(#p3 IS NOT NULL)
SET #SQL += N'
AND [F].[Texto] = #p3';
IF(#p4 IS NOT NULL)
SET #SQL += N '
AND [F].[Fecha] = #p4';
IF(#p5 IS NOT NULL)
SET #SQL += N'
AND [F].[Constitucionailidad] = #p5';
IF(#p6 IS NOT NULL)
SET #SQL += N'
AND [F].[Comentarios] = #p6';
IF(#p7 IS NOT NULL)
SET #SQL = #SQL + '
AND [F].[IdFuente] IN
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Fuentes] [X1]
WHERE
([X1].[Nombre] = #p7)
)';
IF(#p8 IS NOT NULL)
SET #SQL = #SQL + '
AND [F].[IdVigencia] IN
(
SELECT
[X1].[ID]
FROM [dbo].[DP_Vigencia] [X1]
WHERE
([X1].[Nombre] = #p8)
)';
IF(#p9 IS NOT NULL)
SET #SQL = #SQL + '
AND [F].[IdIdentificacion] IN
(
SELECT
[X1].[ID]
FROM [dbo].[DP_TipoFicha] [X1]
WHERE
([X1].[Nombre] = #p9)
)';
IF(#p10 IS NOT NULL)
SET #SQL += N'
AND [F].[NormaNumero] = #p10';
IF(#p11 IS NOT NULL)
SET #SQL = #SQL + '
AND [F].[Publicacion] = #p11';
IF(#p12 IS NOT NULL)
SET #SQL += N'
AND [F].[TemaResumen] = #p12';
EXEC sp_executesql
#SQL,
N'#p1 int,
#p2 varchar(200),
#p3 varchar(200),
#p4 date,
#p5 char(2),
#p6 varchar(200),
#p7 int,
#p8 int,
#p9 int,
#p10 varchar(200),
#p11 varchar(200),
#p12 varchar(200)',
#p1 = #p1,
#p2 = #p2,
#p3 = #p3,
#p4 = #p4,
#p5 = #p5,
#p6 = #p6,
#p7 = #p7,
#p8 = #p8,
#p9 = #p9,
#p10 = #p10,
#p11 = #p11,
#p12 = #p12;
;
GO
I found the answer with the following lines of code:
DECLARE #statement NVARCHAR(4000);
SET #statement = #SQL;
EXECUTE sp_executesql #statement;
I added this to the end of the SP, solved the code issues suggested by SMor and everything worked.
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, ']', ''), '[', '')
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.
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 '.
Using this SP I keep getting an error on the UPDATE statement indicating that I have conversion problem or something. But ID is an integer in all of my tables....
Conversion failed when converting the varchar value 'UPDATE tblLangenUS SET [lang_String] = ' - asdfgsdfg', [prev_LangString] = ' ', [needsTranslation] = 'false' WHERE [ID] = '' to data type int.
#currTable varchar(100),
#ID int,
#short_Text varchar(250),
#brief_Descrip varchar(250) = Null,
#needsTranslation varchar(10) = Null,
#prev_LangString varchar(250) = Null,
#lang_String varchar(250) = Null,
#original_lang_String varchar(250) = Null,
#StringID_from_Master varchar(250),
#GUID varchar(250) = Null
/*
*/
AS
SET NOCOUNT ON;
DECLARE #userTable AS VARCHAR(200);
SET #userTable = #currTable
DECLARE #submitDate1 DATETIME;
SET #submitDate1 = GETDATE()
SET #prev_LangString = #original_lang_String
SET #needsTranslation = 'false'
DECLARE #sql varchar(max)
-- Establish update to the language tabel of user and prepare to search DB for all strings that will need to be updated.
BEGIN
SET #sql = 'UPDATE ' + #currTable + ' SET [lang_String] = ''' + #lang_String + ''', [prev_LangString] = ''' + #prev_LangString + ''', [needsTranslation] = ''' + #needsTranslation + ''' WHERE [ID] = ''' + #ID + '''; '
EXEC #sql
#sql = ''
END
BEGIN
DECLARE usedIN_DBScursor CURSOR
FOR
SELECT tblUniquetblStringsMaster_ID, Database_Name, dbKeyID_ofStringName
FROM tblDBUsage
WHERE (tblUniquetblStringsMaster_ID = #StringID_from_Master );
-- Declare the variables to store the values returned by FETCH.
DECLARE #tblUniquetblStringsMaster_ID AS INT;
DECLARE #dbKEYID as INT;
DECLARE #dbName as varchar(100);
OPEN usedIN_DBScursor;
-- Perform the first fetch and store the values in variables.
-- Note: The variables are in the same order as the columns
-- in the SELECT statement.
FETCH NEXT FROM usedIN_DBScursor
INTO #tblUniquetblStringsMaster_ID, #dbName, #dbKEYID;
-- Check ##FETCH_STATUS to see if there are any more rows to fetch.
WHILE ##FETCH_STATUS = 0
BEGIN
-- Update pending strings table with translation.
BEGIN
INSERT INTO tblPendingDBUpdates
(stringMasterID, databaseName, databaseStringID, englishText, foreignLangText, submitDate, GUID)
VALUES (#StringID_from_Master, #dbName, #dbKEYID, #short_Text, #lang_String, #submitDate1, #GUID);
END
-- SET #sql = ''
-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM usedIN_DBScursor
INTO #tblUniquetblStringsMaster_ID, #dbName, #dbKEYID;
END
CLOSE usedIN_DBScursor;
DEALLOCATE usedIN_DBScursor;
END
RETURN
If the ID is an int, you must CAST it to an nvarchar
SET #sql = 'UPDATE ' + #currTable + ' SET [lang_String] = ''' + #lang_String + ''', [prev_LangString] = ''' + #prev_LangString + ''', [needsTranslation] = ''' + #needsTranslation + ''' WHERE [ID] = ''' + CAST(#ID as nvarchar(10)) + '''; '
Otherwise, you are trying to add a string and an integer together, which won't work.
Notice this part:
' WHERE [ID] = ''' + CAST(#ID as nvarchar(10)) + '''
I think you must also change your EXEC syntax to:
EXEC(#sql)