increase counter while using exec - sql

I want to use a counter in a way like the below one:
exec
('begin insert into ' + #temp07 + ' (FileID,FileName)
Select aof_id,aof_fileName from PaFi07(' + #partId + ');
sp_executesql #sqlCounter, N'#intCount int output, #intConst int, #intCount = #intCount output, #intConst = #intConst
end')
so how can i let the counter work?
any suggestion that the counter work inside this EXEC command
THANX

You cannot EXEC them as EXEC runs in its own scope so the variable identifiers have no meaning.
You can instead declare them as ints, pass them to sp_executesql along with a statement string and return the result as an output;
declare #sql nvarchar(256) = 'SET #intCount = #intCount + #intConst'
EXEC sp_executesql #sql,
N'#intCount int output, #intConst int',
#intCount = #intCount output,
#intConst = #intConst
select #intCount
>6

There are several errors in your snippet:
First of all, you are declaring your variables as varchar(10), while you are intending to use them as numbers. They should be declared as smallint, int or bigint.
Then you are composing a string using those varchar variables and trying to add 1 to the value stored in #inCount with an addition of the number 1.
Since your variables are strings and not numbers, the + symbols tries to concatenate them.
To realize about your error, first, you should convert the number 1 to a string, writing the EXEC like this:
exec ('SET ' + #intCount + ' = ' + #intCount + '1')
Once you have done that, just remove the EXEC and assign the string you are concatenating to a new string variable. So:
DECLARE #composedQuery varchar(1000)
SET #composedQuery = 'SET ' + #intCount + ' = ' + #intCount + '1'
SELECT #composedQuery
You will see a result like this:
SET 5 = 51
For sure, this is not what you are intending to execute with EXEC, isn't it? :)
The correct solution has been given to you in other answers. I rewrite the full snippet:
declare #intCount int
declare #intConst int
set #intCount = 5
set #intConst = 1
SET #intCount = #intCount + 1
--OR
SET #intCount = #intCount + #intConst

You don't need exec for that:
set #inCount = #intCount + #intConst
If you want to use exec, you would use the name of the variables in the string, not the values:
exec('set #inCount = #intCount + #intConst')
Edit:
For the new question; you would concatenate the values into the string:
exec
('begin insert into ' + #temp07 + ' (FileID,FileName)
Select aof_id,aof_fileName from PaFi07(' + #partId + ');
sp_executesql #sqlCounter, N'#intCount int output, #intConst int, #intCount = ' + #intCount + ' output, #intConst = ' + #intConst + ' end')
If they are numeric values you would need to cast them:
... + cast(#intCount as varchar) + ...

Related

SQL Server output param truncated where it is too long

I have 4 stored procedures.
The following is used to be invoked by C#:
ALTER PROCEDURE [dbo].[sp_retrieveResourceShell]
AS
BEGIN
SET NOCOUNT ON
DECLARE #result NVARCHAR(MAX)
EXEC [dbo].[sp_retrieveResTree]
#pid = NULL,
#ret = #result OUTPUT
***select*** #result
END
These are internal stored procedures:
ALTER PROCEDURE [dbo].[sp_retrieveResTree]
(#pid UNIQUEIDENTIFIER,
#ret NVARCHAR(MAX) OUTPUT)
AS
BEGIN
DECLARE #mdlId UNIQUEIDENTIFIER,
#mdlGroup NVARCHAR(MAX)
DECLARE mdlCursor CURSOR FOR
......
DECLARE #subRet NVARCHAR(MAX),
#viewRet NVARCHAR(MAX)
EXEC [dbo].[sp_retrieveResTree]
#pid = #mdlId,
#ret = #subRet OUTPUT
EXEC dbo.sp_retrieveResView
#mdlId = #mdlId,
#ret = #viewRet OUTPUT
SET #mdlGroup = #mdlGroup + FORMATMESSAGE('{"Id":"%s","Name":"%s","Subs":%s,"Views":%s},'...)
.......
SET #ret = FORMATMESSAGE('[%s]',#mdlGroup)
END
ALTER PROCEDURE [dbo].[sp_retrieveResView]
(#mdlId UNIQUEIDENTIFIER,
#ret NVARCHAR(MAX) OUTPUT)
AS
BEGIN
SET #ret = FORMATMESSAGE('[%s]',#viewGroup)
END
When I invoke sp_retrieveResourceShell like this:
DECLARE #return_value int
EXEC #return_value = [dbo].[sp_retrieveResourceShell]
SELECT 'Return Value' = #return_value
I can get a truncated string with ellipsis at the string tail.
how to get the full string without ellipsis?
update
Changed formatmessage function to string concatenation likes
SET #mdlGroup = #mdlGroup + '{"Id":"' + CAST(#mdlId AS CHAR(36))+ '","Name":"' + #mdlName + '","Subs":' + #subRet + ',"Views":' + #viewRet +'},'
when using string concatenation , likes
SET #ret = N'[' + #mdlGroup + N']'
and refernce to [n]varchar(max) + [n]varchar(max)
i got the right full string . Thanks to #MartinSmith at the same time .

Why do I get a "must declare scalar variable" error in dynamic SQL?

I am trying to use Dynamic SQL when setting a value to a variable, but it doesn't work. However, the same statement does work in regular SQL. This is the code:
DECLARE #sqlcmd nchar(1024);
DECLARE #DBName nchar(30) = 'DB_1016a'
DECLARE #UserKey int = 0;
DECLARE #UserID nchar(30) = 'DBCLIENT\StudentA'
set #sqlcmd = 'set #UserKey = (SELECT [Key] from ' + rtrim(ltrim(#DBName)) + '.dbo.userlist where ID = ''' + rtrim(ltrim(#UserID)) + ''')'
print(#sqlcmd)
exec(#sqlcmd)
print('stuff1')
print('['+rtrim(ltrim(cast(#UserKey as nchar(4))))+']')
print('stuff2')
And this is what it returns:
set #UserKey = (SELECT [Key] from DB_1016a.dbo.userlist where ID = 'DBCLIENT\StudentA')
*Msg 137, Level 15, State 1, Line 30
Must declare the scalar variable "#UserKey".*
stuff1
[0]
stuff2
What am I doing wrong?
You need to bind an output parameter in the dynamic SQL batch and assign your local variable to the parameter. Like this:
DECLARE #sqlcmd nchar(1024);
DECLARE #DBName nchar(30) = 'DB_1016a'
DECLARE #UserKey int;
DECLARE #UserID nchar(30) = 'DBCLIENT\StudentA'
set #sqlcmd = 'set #UserKey = (SELECT [Key] from ' + rtrim(ltrim(#DBName)) + '.dbo.userlist where ID = ''' + rtrim(ltrim(#UserID)) + ''')'
print(#sqlcmd)
exec sp_executesql #sqlcmd, N'#UserKey int out', #UserKey = #UserKey output
print('stuff1')
print('['+rtrim(ltrim(cast(#UserKey as nchar(4))))+']')
print('stuff2')
You're dealing with a scope issue. The statement contained in #sqlcmd is in a different execution scope than that where you declare #UserKey when you run it with exec.

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;

Dynamic sql stored procedure update query issue?

I've written the below code to set filepath column in my table as 'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\SR_1.txt'
where SR_1 is file_name column
.txt is file_ext column from my table.
but after executing following procedure, I'm getting filepath column in table as
'F:\DataMigration\Wise\DELTA_20121008\Attachments\file_name.file_ext'
means It's treating column names as string, how i can make it as column so it will
use values in that column.
alter procedure [dbo].[WISEMissingAttachmentReportGenerator]
(
#tablename varchar(255), #pathonlocal nvarchar(255)
)
as
begin
--step 1
exec dbo.proc_alter_table #tablename
--step 2
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ' file_name'+'.'+'file_ext''')
EXEC('Select * from '+#tablename)
end
exec [dbo].[WISEMissingAttachmentReportGenerator] [WISE.Non_VP_Service_Request_Attachments_File_Check_Analysis],
N'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\'
Try;
EXEC('UPDATE '+ #tablename +
' SET filepath = '''+ #pathonlocal + ''' + file_name + '''+'.'+''' + file_ext')
Equal as;
UPDATE [YourTable] SET filepath = 'YourPath' + file_name + '.' + file_ext
Try changing your statement to this:
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ''' + file_name + ''.'' + file_ext')
declare #tblnm varchar(20) = 'test'
declare #upda varchar(20) = 'update '
declare #set varchar(25) = ' set'
declare #id varchar(25) = ' id'
declare #cmd varchar(1000)
set #cmd = #upda + #tblnm + #set + #id + '=7'
exec(#cmd)
SAMPLE SQL UPDATE QUERY - FOR BUILDING TABLENAME DYNAMICALLY
EXECUTED GUYS - THIS IS CALL JUGAAAAAAAAAD [NO NEED TO GET INTO ''' STUFF]