Stored Procedure Count - sql-server

I am trying to get a dynamic count to print out but it is telling me
#totalCAUUpdates needs a scalar value. Any thoughts?
declare #totalCAUUpdates as int = 0;
declare #realTableName as varchar(100) = '[_TEMP_SubscriptionTransactionsForMosoPay09022014]'
declare #updateSQL as varchar(1000) = 'select #totalCAUUpdates = count(*) from ' + #realTableName + ' where len(accountNumberUpdated) > 0 OR len(accountAccessoryUpdated) > 0;';
raiserror (#updateSQL, 0,1) with nowait;
EXEC (#updateSQL);

DECLARE #totalCAUUpdates INT= 0;
DECLARE #updateSQL NVARCHAR(MAX);
DECLARE #realTableName SYSNAME;
SET #realTableName = '_TEMP_SubscriptionTransactionsForMosoPay09022014';
SET #updateSQL = N'select #totalCAUUpdates = count(*) from ' + QUOTENAME(#realTableName)
+ N' where len(accountNumberUpdated) > 0 OR len(accountAccessoryUpdated) > 0;';
EXECUTE sp_executesql #updateSQL
,N'#totalCAUUpdates INT OUTPUT'
,#totalCAUUpdates OUTPUT

your batch is being executed inside another session, where #totalCAUUpdates is not visible.
You need to use sp_ExecuteSQL instead.. This proc allows you to pass in values declared in the calling session and use them with a declared variable in the called session

Related

Set #Variable1 within a stored proc by executing #Variable2

I want to set the value of #Count by executing #Counter within a Begin Try of a stored procedure.
SET #Counter ='SET #Count = (SELECT COUNT(' + #COLUMN + ') FROM ' + #TABLE + ' WHERE CONVERT(VARCHAR(MAX),' + #COLUMN + ') = ''' + #DATATOFIND + ''')'
I have tested the above code and it does give me the expected result for populating the #Count variable inside of a normal sql statement outside of a stored procedure.
Once the #Count variable is populated I want to use it in a print statement.
PRINT '-- No. of Entries in the ' + #TABLE + ' Table = ' + #Count
I have tried to the following two options to get the #Count populated but neither has worked
EXEC #Counter
and
EXECUTE sp_executesql (#Counter)
UPDATE:
After some more research I tried this:
DECLARE #Counter NVARCHAR(1000)
SET #Counter = N'DECLARE #Count NVARCHAR(100); SET #COUNT = (SELECT COUNT(UserId) FROM UserGrp WHERE CONVERT(VARCHAR(MAX),UserId) = ''za02'')'
EXECUTE sp_executesql #Counter
Print #Count
But I receive this error:
Must declare the scalar variable "#Count"
UPDATE: Workaround / Solution to my situation
DECLARE #Counter NVARCHAR(2000)
SET #Counter = 'DECLARE #Count NVARCHAR(100); SET #COUNT = (SELECT COUNT(UserId) FROM UserGrp WHERE CONVERT(VARCHAR(MAX),UserId) = 'to01'); Print '/* No. of Entries in the UserGrp Table - ' + #Count + ' */''
EXEC (#Counter)
This gives me clear information in my result to decide what to do with the created code from the rest of the stored proc
Dynamic SQL requires careful handling:
DECLARE #Counter NVARCHAR(1000);
DECLARE #COUNT BIGINT;
DECLARE #DATATOFIND VARCHAR(100) = 'za02';
DECLARE #TABLE SYSNAME = N'UserGrp';
DECLARE #COLUMN SYSNAME = N'UserId';
SET #Counter = N'SELECT #COUNT = COUNT(<column_name>)
FROM <table_name>
WHERE CONVERT(VARCHAR(MAX),<column_name>) = #DATATOFIND;';
SET #Counter = REPLACE(#Counter, '<column_name>', QUOTENAME(#COLUMN));
SET #Counter = REPLACE(#Counter, '<table_name>', QUOTENAME(#TABLE));
PRINT #Counter; -- debug
EXECUTE sp_executesql #Counter,
N'#DATATOFIND VARCHAR(100), #COUNT BIGINT OUTPUT',
#DATATOFIND,
#COUNT OUTPUT;
SELECT #COUNT;
db<>fiddle demo
Minimum:
params are parameters, not concatenated string
identifiers(here column/table name) - should be quoted for instance using QUOTENAME function
it is good to print query to see if it doing what is expected
parameters set inside dynamic query could be passed to outer block by defining them as OUTPUT

Execute dynamic query that executes another stored procedure

I have a query like this:
DECLARE #TaskId UNIQUEIDENTIFIER
DECLARE #TaskName VARCHAR(255) = 'MasterSet'
DECLARE #sql NVARCHAR(MAX)
DECLARE #StartingDateTask DATETIME2 = (SELECT TOP 1 [Date]
FROM [TaskStatusAudit]
WHERE [TaskId] = 'A1FDFC16-904D-4560-B19D-5E7D4FEB1C2B'
AND [TaskStatusName] = 'IN-PROGRESS')
DECLARE #EndingDateTask DATETIME2 = (SELECT TOP 1 [Date]
FROM [TaskStatusAudit]
WHERE [TaskId] = 'A1FDFC16-904D-4560-B19D-5E7D4FEB1C2B'
AND [TaskStatusName] = 'COMPLETED')
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as ' + quotename(#TaskName) + N''
EXEC sp_executesql #sql
Problem is when I execute it I get this error:
Must declare the scalar variable "#StartingDateTask".
Any ideas why I getting that if I declare my variable correctly? Regards
When executing sp_executesql you need to declare and pass the variables to sp_executesql something like..
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as '
+ quotename(#TaskName) + N''
exec sp_executesql #sql
, N'#StartingDateTask DATETIME2 , #EndingDateTask DATETIME2'
, #StartingDateTask
, #EndingDateTask
Second parameter is the variable declaration parameter followed by the actual variables separately.
You can also do like taking a parameters variable and assign it.
declare #params nvarchar(100)
set #params='#StartingDateTask DATETIME2,#EndingDateTask DATETIME2'
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as '
+ quotename(#TaskName) + N''
exec sp_executesql #sql
, #params
, #StartingDateTask
, #EndingDateTask

How to set value to declared variable in SQL Server

How to set value to declared variable in SQL Server.
DECLARE #V_SEQUENCE INT, #V_SEQUENCENAME NVARCHAR(MAX);
SET #V_SEQUENCENAME = 'dbo.MYSEQ';
EXEC('SELECT #V_SEQUENCE = NEXT VALUE FOR ' + #V_SEQUENCENAME)
SELECT #V_SEQUENCE
Here i am getting an error:
Must declare the scalar variable "#V_SEQUENCE"'
Please tell me how to get result of #V_SEQUENCE.
You want to pass a value out of the execute. I recommend that you use sp_executesql:
DECLARE #V_SEQUENCE INT, #V_SEQUENCENAME NVARCHAR(MAX), #SQL NVARCHAR(MAX);
SET #V_SEQUENCENAME = 'dbo.MYSEQ';
SELECT #SQL = 'SELECT #V_SEQUENCE = NEXT VALUE FOR ' + #V_SEQUENCENAME;
EXEC sp_executesql #SQL, N'#V_SEQUENCE INT OUTPUT', #V_SEQUENCE = #V_SEQUENCE OUTPUT;
SELECT #V_SEQUENCE;

Using dynamic WHERE clause with sp_executesql

I can not get dynamic where clause working. The query I use:
IF NOT EXISTS ( SELECT *
FROM sys.tables
WHERE name = 'a' )
BEGIN
CREATE TABLE a ( a INT );
END;
DECLARE #whereClause NVARCHAR(MAX) = ' 1=1 ';
DECLARE #sql NVARCHAR(MAX) = 'SELECT * FROM a WHERE #whereClause';
EXEC sp_executesql #sql, N'#whereClause NVARCHAR(MAX)', #whereClause;
DROP TABLE a;
Then additional question would be: is there any possibility to debug query that is executed with sl_executesql?
As as been stated you can't use the parameters on sp_executesql to replace statement objects, only parameter variables.
If you need to build the WHERE clause dynamically, I find it easier to use REPLACE for the Object components of the statement.
DECLARE #whereClause NVARCHAR(MAX) = ' 1=#whereVariable ';
DECLARE #whereVariable INT = 1;
DECLARE #sql NVARCHAR(MAX) = 'SELECT * FROM a WHERE #whereClause';
SELECT #sql = REPLACE(#sql, '#whereClause', #whereClause)
EXEC sp_executesql #sql
,'#whereVariable INT'
,#whereVariable = #whereVariable;
This means that the statement can be built without interlived + and variables. It then means that the input and output parameters are used as normal.

how to assign the integer value to nvarchar or varchar datatype in stored procedure

how to assign the integer value to nvarchar or varchar datatype in stored procedure
DECLARE #SQLString nvarchar(max)
SET #SQLString = N'declare #Identifier int;
SELECT COUNT(*) FROM ' + #batch+' where Identifier = #Identifier'
i need to check whether the #SQLString is 0 or not.
i.e i want to check -----> if(#SQLString =0). how to assign a integer val to nvarchar or varchar
You could try something like
DECLARE #IntVal INT,
#ParamDef NVARCHAR(MAX),
#SQLString nvarchar(max),
#batch VARCHAR(MAX)
SELECT #batch = 'Batch',
#SQLString = N'SELECT #IntVal = COUNT(*) FROM ' + #batch,
#ParamDef = '#IntVal INT OUTPUT'
EXECUTE sp_executesql #SQLString,#ParamDef, #IntVal=#IntVal OUT
SELECT #IntVal
Have a look at sp_executesql (Transact-SQL)
I think this way is best:
DECLARE
#Cnt int,
#SQL nvarchar(max),
#batch sysname,
#Identifier varchar(30)
-- set #batch and #Identifier
SET #SQL = 'SELECT #Cnt = Count(*) FROM ' + #batch
+ ' WHERE Identifier = #Identifier'
EXEC sp_executesql #SQL, N'#Cnt int OUT, #Identifier varchar(30)',
#Cnt OUT, #Identifier
IF #Cnt = 0 BEGIN
--do something
END
ELSE BEGIN
--do something else
END
Though if you only care whether it's 0 or not, then you should do this instead, which can stop after finding only one row, instead of having to count them all:
DECLARE
#HasRows bit,
#SQL nvarchar(max),
#batch sysname,
#Identifier varchar(30)
-- set #batch and #Identifier
SET #SQL = 'SET #HasRows = CASE WHEN EXISTS (SELECT 1 FROM '
+ #batch + ' WHERE Identifier = #Identifier) THEN 1 ELSE 0 END'
EXEC sp_executesql #SQL, N'#HasRows bit OUT, #Identifier varchar(30)',
#HasRows OUT, #Identifier
IF #HasRows = 0 BEGIN
--do something
END
ELSE BEGIN
--do something else
END
However, if there's any way you can avoid using dynamic SQL and changing table names, that would be best. Then it is a simple query:
IF NOT EXISTS (SELECT 1 FROM TableName WHERE Identifier = #Identifier) BEGIN
-- do something
END
You're setting #SQLString to a query... if you want to see if it's '0', then you can just do:
IF #SQLString = '0'
But I think you're trying to find out if there are 0 rows in your batch, in which case, you mean something more like:
DECLARE #Res TABLE (cnt int);
INSERT #Res exec sp_executesql #SQLString;
IF (SELECT MAX(cnt) FROM #Res) = 0 /* Means empty batch */
convert it:
SET #var = CONVERT(VARCHAR, #intval)
Sascha
I am assuming that you are trying to check how many rows the dynamic sql returned you can do something like this:
DECLARE #SQLString nvarchar(max)
SET #SQLString = N'declare #Identifier int;
SELECT * FROM ' + #batch+' where Identifier = #Identifier'
exec #SQLString
set #SQLString = ##ROWCOUNT
if #SQLString = 0
begin
...
end

Resources