SQL Server dynamic procedure 2 - sql

USE KronosNET22
GO
Create procedure eventossucursales4
#id nvarchar(max),
#dia nvarchar(max)
as
begin
declare #sqlstring nvarchar(max)
set #sqlstring = 'Select Code From ' + #dia + ' WHERE idObject = ''' + #id + ''' AND (CODE = ''TFHi2'' OR CODE = ''E603'')'
EXEC sp_executesql #sqlstring, #id,#dia
end
GO
Execute eventossucursales4 'E4211537-09CD-45F2-BB5F-F20F642DE676','ObjectSignal_2016_05_23 '
Error:
Mens. 102, Nivel 15, Estado 1, LĂ­nea 1
Sintaxis incorrecta cerca de 'E4211537'.
Can someone help me to figure it out why its showing a mistake in the declaration of the variable?

You could eliminate passing the parameters as someone commented. If you want to make it work as is, you need to add the parameter list. I was able to get it working this way.
alter procedure eventossucursales4
#id nvarchar(max),
#dia nvarchar(max)
as begin
declare #sqlstring nvarchar(max)
declare #ParmDefinition nvarchar(500) = '#dia nvarchar(max), #id nvarchar(max)'
set #sqlstring = 'Select Code From ' + #dia + ' WHERE idObject = ''' + #id + ''' AND (CODE = ''TFHi2'' OR CODE = ''E603'')'
exec sp_executesql #sqlstring, #ParmDefinition, #id = #id, #dia = #dia
end
GO
Execute eventossucursales4 'E4211537-09CD-45F2-BB5F-F20F642DE676','ObjectSignal_2016_05_23 '

Related

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.

How to pass Server Name dynamically in SQL Server

SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX),
#servername NVARCHAR(255)
SET #servername = '[s-printstream]'
--Drop Table #Actual
CREATE TABLE #Actual
(
jobnumber INT,
firstNameCounts VARCHAR(25),
lastNameCounts VARCHAR(25),
address1Counts VARCHAR(25),
address2Counts VARCHAR(25),
cityCounts VARCHAR(25),
stateCounts VARCHAR(25),
zipCounts VARCHAR(25),
inHomeDateCounts VARCHAR(25)
)
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts , address1Counts, address2Counts, cityCounts, stateCounts, zipCounts, inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS [firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1) As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count (s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count (jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From' + ' #servername ' + '.[tdis_417133]' + '.[dbo].[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
SET #sql = #sql + ' where jobNumber = #jobNumber '
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC sp_executesql #sql
,N'#JobNumber Varchar(25)'
,#JobNumber = 417133
Could anyone please help me find out how I would pass my server name dynamically as well as the database name? When I try to do it, I get this error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#servername"
Any help is appreciated.
Thanks
or pass #servername value into sql command
EXEC sp_executesql #sql
,N'#JobNumber Varchar(25),#servername nvarchar(255)'
,#JobNumber = 417133,#servername=#servername

sp_executesql returns nothing when parameter is null

I've got this piece of code in my procedure:
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #inserted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #NEW out
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #deleted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #OLD out
And when the column value is null the variable #OLDdoesn't have nothing and for some reason when I compare the 2 variables:
IF #NEW != #OLD
It doesn't get inside the IF, even if the #OLD is empty and #NEW isn't. I've tried this:
IF #OLD is null or datalength(#OLD)=0 or #NEW != #OLD
But still no good result. When I print the 2 variables the #OLD doesn't print anything (in the cases where is null in the table).
Can you help me?
Thank you :)
EDIT
This is a trigger that I built for some tables in my database when they're updated so I can save the changes made. To make it easy I created a loop trough the columns name of that table and for every column I do that piece of code that its giving me problems. Here's a bit more of my trigger:
WHILE(#LoopCounter <= #MAX)
BEGIN
SELECT #Column = COLUMN_NAME, #Type = DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS WHERE ORDINAL_POSITION = #LoopCounter and TABLE_NAME = 'Parameters'
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #inserted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #NEW out
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #deleted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #OLD out
IF #OLD is null or datalength(#OLD)=0 or #NEW != #OLD
BEGIN
/* some code */
END
SET #LoopCounter = #LoopCounter + 1
END
So check null states:
IF #NEW != #OLD
OR #NEW IS NULL AND #OLD IS NOT NULL
OR #OLD IS NULL AND #NEW IS NOT NULL
BEGIN
...
Why not go proactive...don't execute if your #Column is null..
WHILE(#LoopCounter <= #MAX)
BEGIN
SELECT #Column = COLUMN_NAME, #Type = DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS WHERE ORDINAL_POSITION = #LoopCounter and TABLE_NAME = 'Parameters'
IF ISNULL(#Column,'')<>''
BEGIN
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #inserted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #NEW out
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #deleted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #OLD out
IF #OLD is null or datalength(#OLD)=0 or #NEW != #OLD
BEGIN
/* some code */
END
END
SET #LoopCounter = #LoopCounter + 1
END
Ok, I found a solution. Thank you for your tips. I changed my code to:
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #inserted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #NEW out
SET #Sql = 'SELECT #Value = ' + #Column + ' FROM #deleted'
exec sp_executesql #Sql, N'#Value varchar(MAX) out', #OLD out
IF ISNULL(#NEW,0) != ISNULL(#OLD,0)
With ISNULLeverything goes ok. I've also had to use this in another place in my code where I was concatenating a stringwith the #OLDand #NEW values.
Thank you :)

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;