How to assigning value to parameter in dynamic query inside cursor - sql

My problem is in the line with EXEC, all works except adding value to #counter.
If I execute something like below there is no problem:
EXEC('if exists(select * from '+ #table + ' where ' + #column + ' = ' + #someValue + ') print ''test''');
What to do to add value to the #counter? When I'm running below code I'm getting error:
Incorrect syntax near 0.
CREATE PROCEDURE testSP
AS
BEGIN
DECLARE testCursor CURSOR;
DECLARE #table NVARCHAR;
DECLARE #column NVARCHAR;
DECLARE #someValue NVARCHAR;
...
BEGIN
DECLARE testCursor2 CURSOR;
DECLARE #counter INT = 0;
...
BEGIN
DECLARE #result INT = 0;
EXEC( 'if exists(select * from '+ #table + ' where ' + #column + ' = ' + #someValue + ') set ' + #counter + '=1' );
IF (#counter > 0)
PRINT 'test';
...
END
...
END
END
go

You can use this.
CREATE PROCEDURE testSP
AS
BEGIN
DECLARE testCursor CURSOR;
DECLARE #table NVARCHAR;
DECLARE #column NVARCHAR;
DECLARE #someValue NVARCHAR;
...
BEGIN
DECLARE testCursor2 CURSOR;
DECLARE #counter INT = 0;
...
BEGIN
DECLARE #result INT = 0;
declare #sqlText nvarchar(max)= N'if exists(select * from '+ #table + ' where ' + #column + ' = ' + #someValue + ') SET #counter = 1'
DECLARE #ParmDefinition nvarchar(500) = N'#counter INT OUTPUT';
EXEC sp_executesql #sqlText, #ParmDefinition, #counter = #counter OUTPUT ;
if(#counter>0)
print 'test';
...
END
...
END
END

Related

Run a dynamic SQL query from a stored procedure to populate a GridView

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.

Dynamic SQL - parametrized query

I use dynamic sql with parameters and have problem :)
In block of code it works, but when I call procedure I have error that I need to declare scalar variable #name_dummy
So:
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT
o.SCHEMA_N
,o.TABLE_N
,o.Condition
,o.TargetDB
,o.SourceDB
,STUFF((SELECT
', ' + c.name
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH (''))
, 1, 1, '')
FROM Table_A o
ORDER BY 1,
2
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = ( SELECT CAST(Wartosc AS VARCHAR) FROM Table_B WHERE Id = 3 )
IF #TOP < 40000
SET #TOP = 40000
WHILE ( 1 = 1 )
BEGIN
DECLARE #CHECK BIT = 0
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM '
+ #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
SELECT #sqlCMD , #CHECK
END
END
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
CLOSE KUR;
DEALLOCATE KUR
And when I execute this it's compiling and works ( returns values ) for example sql which I want to execute.
SELECT TOP 1 #check_exists = 1 FROM MSSF15_WarstwaPosrednia.KatalogZdarzen.MSSF_RaportZdarzenPLKB2CS2K WHERE StatusPrzetwarzania = 4 AND DataWpisu < DATEADD(MONTH, -3, #START_TIME)
Parameters work here ( #check_exists which is output and #START_TIME condition param ) , but when I execute this in procedure I'm getting error
Must declare the scalar variable "#START_TIME". 137
SP definition:
USE xxxx
/****** Object: StoredProcedure dbo.dummy Script Date: 06/09/2018 13:40:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE dbo.dummy
AS
BEGIN
/*
PRZENIESIENIE DANYCH
*/
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT o.SCHEMA_N,
o.TABLE_N,
o.Condition,
o.TargetDB,
o.SourceDB,
STUFF((
SELECT ', ' + c.NAME
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH('')
), 1, 1, '')
FROM dbo.Table_A o
ORDER BY 1,
2
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = (
SELECT CAST(Wartosc AS VARCHAR)
FROM dbo.Table_B
WHERE Id = 3
)
IF #TOP < 40000
SET #TOP = 40000
WHILE (1 = 1)
BEGIN
BEGIN TRY
BEGIN TRANSACTION T_TEST
DECLARE #CHECK BIT = 0
DECLARE #START_TIME_P DATE = GETDATE()
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
SELECT #CHECK,
#START_TIME_P,
#sqlCMD
EXEC sp_executesql #sqlCMD,
N'#check_exists bit OUTPUT, #START_TIME DATE',
#check_exists = #CHECK OUTPUT,
#START_TIME = #START_TIME_P;
IF OBJECT_ID('tempdb..#TMP_ID') IS NOT NULL
DROP TABLE #TMP_ID
CREATE TABLE #TMP_ID (Id INT)
EXEC (
'INSERT INTO #TMP_ID
SELECT TOP ' + #TOP + ' Id
FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
)
DECLARE #sqlCMD_Ins NVARCHAR(MAX)
SET #sqlCMD_Ins = 'INSERT INTO ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' '
SET #sqlCMD_Ins = #sqlCMD_Ins + 'SELECT ' + #COLUMN_LIST + ' FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Ins IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Ins)
DECLARE #sqlCMD_Del NVARCHAR(MAX)
SET #sqlCMD_Del = 'DELETE FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Del IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Del)
DROP TABLE #TMP_ID
COMMIT TRANSACTION T_TEST
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION T_TEST
PRINT 'Wycofanie zmian'
PRINT ERROR_MESSAGE() + ' ' + CAST(ERROR_NUMBER() AS VARCHAR(256))
END
END CATCH
IF #CHECK = 0
BREAK
END
EXEC ('SELECT ''' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' UNION ALL ' + 'SELECT ''' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N)
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
END
CLOSE KUR;
DEALLOCATE KUR;
DECLARE #END_TIME DATETIME = GETDATE()
SELECT 'Daty przetworzenia',
#START_TIME_P AS 'START',
#END_TIME AS 'END'
SELECT 'Czas (min)',
DATEDIFF(MINUTE, #START_TIME_P, #END_TIME)
END
Guys, maybe u have similar situation and can help.
Error msg
Wycofanie zmian
Must declare the scalar variable "#START_TIME". 137
Thanks
Instead of
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
try
declare #date_in DATE = GETDATE()
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #date_in;

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.

SQL Server - Cursor Error

I am declaring a dynamic cursor due to a nesting of the stored procedure based on a parent-child relationship of the data that can go multiple levels and vary daily when processed. The stored procedure works for the parent call, however the process of this procedure for child data causes a message stating that the "Cursor is not open." This message occurs on the Fetch which is immediately after checking to be sure the cursor is open.
DECLARE #OutCur CURSOR;
DECLARE #curName as NVARCHAR(MAX);
...
SET #curName = LEFT(replace(replace(CONVERT (time, GETDATE()),':',''),'.',''),8);
SET #sqlCommand = 'SELECT a.myfields FROM mytable a;
SET #sqlCommand = 'SET #cursor' + #curName + ' = CURSOR LOCAL FAST_FORWARD FOR ' + #sqlCommand + ' OPEN #cursor' + #curName + ';'
SET #curName = '#cursor' + #curName + ' cursor output';
EXEC sys.sp_executesql #sqlCommand,#curName,#OutCur output
IF CURSOR_STATUS('global','#OutCur')=-1
OPEN #OutCur;
FETCH NEXT FROM #OutCur INTO #name,#type
Thanks in advance for the input.
if you uncomment close+deallocate - script works fine:
GO
DECLARE #OutCur CURSOR;
DECLARE #curName as NVARCHAR(MAX), #sqlCommand nvarchar(max), #name varchar(100), #type varchar(100)
declare #i int = 0
while #i < 5
begin
SET #curName = LEFT(replace(replace(CONVERT (time, GETDATE()),':',''),'.',''),8);
SET #sqlCommand = 'SELECT ''111'' as name, ''cc'' as type; '
SET #sqlCommand = 'SET #cursor' + #curName + ' = CURSOR LOCAL FAST_FORWARD FOR ' + #sqlCommand + ' OPEN #cursor' + #curName + ';'
SET #curName = '#cursor' + #curName + ' cursor output';
EXEC sys.sp_executesql #sqlCommand,#curName,#OutCur output
FETCH NEXT FROM #OutCur INTO #name,#type
select #name, #type
--close #OutCur
--deallocate #OutCur
set #i += 1
end
GO

Store the result of a Dynamic Query in a variable

I know this question has been asked, and I already found some solutions in internet.. but I still can not make it work properly.
So.. I have to make a SELECT query and store the result in a variable (I DONT want a table variable).
My problem is that the name of the table is also a variable. The table name changes accordingly to a WHILE, here is my code:
DECLARE #numRecord INT;
DECLARE #maxMacNumber INT;
SET #maxMacNumber = 500;
DECLARE #mac INT;
SET #mac = 0;
DECLARE #res FLOAT;
DECLARE #ap INT;
SET #ap = 0;
DECLARE #apString VARCHAR(2);
DECLARE #numRecordString VARCHAR(20);
DECLARE #tablename VARCHAR(500);
DECLARE #sql NVARCHAR(500);
DECLARE #varDefinition NVARCHAR(200);
WHILE #mac <= #maxMacNumber
BEGIN
SET #numRecord = 6 + #mac * 390;
SET #ap = 0;
WHILE #ap < 2
BEGIN
SELECT #apString = CONVERT(VARCHAR,#ap);
SELECT #numRecordString = CONVERT(VARCHAR, #numRecord);
SELECT #rssiString = CONVERT(VARCHAR, #rssi);
SET #tablename = 'APDB.dbo.AP' + #apString;
SET #sql = 'SELECT RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;
-- HERE I WILL DO SOMETHING WITH #res
END;
END;
The problem is that it doesn't print anything when I do PRINT #res...
This is the relevant SQL code:
SET #sql = 'SELECT RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;
You are never setting #res in the SQL. Try this:
SET #sql = 'SELECT #res = RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;