T-SQL FETCH_STATUS Alternative - sql-server

I have a stored procedure below. In it is a nested loop. Instead of using FETCH_STATUS I want to use something else to mark my cursor as being finished, so that I can do a nested loop. But it's never picking up #Client_ID in the cursor and I don't know why.
ALTER PROCEDURE [dbo].[Import_Agent_Client_Bucket_2010]
AS
BEGIN
-- Loop Through Each Agent, Create a Bucket, Add their Clients to the Bucket
DECLARE Agent_Cursor CURSOR FOR
SELECT TOP 10 Agent_GUID, Agent_ID
FROM realforms_2011.dbo.Agent
DECLARE #Agent_GUID uniqueidentifier
DECLARE #Agent_ID int
OPEN Agent_Cursor;
FETCH NEXT FROM Agent_Cursor
INTO #Agent_GUID, #Agent_ID;
DECLARE #MaxAgentCount int
SELECT #MaxAgentCount = COUNT(Agent_ID)
FROM Agent
DECLARE #AgentCounter int
SET #AgentCounter = 0
WHILE (1 < 2)
BEGIN
PRINT 'Agent Counter:'
PRINT #AgentCounter
SET #AgentCounter = #AgentCounter + 1
-- Create a bucket for each agent
DECLARE #cbPKTable TABLE (cbPK UNIQUEIDENTIFIER, cbID int)
INSERT INTO realforms_2011.dbo.Client_Bucket ([Description] ) OUTPUT inserted.Client_Bucket_GUID, inserted.Client_Bucket_ID INTO #cbPKTable
SELECT ISNULL(a.First_Name, ' ') + ' ' + ISNULL(a.Last_Name, ' ') + '''s Clients'
FROM realforms_2011.dbo.Agent a
WHERE Agent_GUID = #Agent_GUID
DECLARE #Client_Bucket_GUID uniqueidentifier
SELECT #Client_Bucket_GUID = cbPK FROM #cbPKTable
PRINT 'Client Bucket GUID Inserted:'
PRINT #Client_Bucket_GUID
DECLARE #Client_Bucket_ID int
SELECT #Client_Bucket_ID = cbID FROM #cbPKTable
INSERT INTO realforms_2011.dbo.Agent_Client_Bucket (Agent_GUID, Agent_ID, Client_Bucket_GUID, Client_Bucket_ID)
VALUES (#Agent_GUID, #Agent_ID, #Client_Bucket_GUID, #Client_Bucket_ID)
DECLARE #Client_GUID uniqueidentifier
DECLARE #Client_ID int
-- Get clients from the server (2010)
DECLARE Client_Cursor CURSOR FOR
SELECT C.Client_ID
FROM realforms.dbo.Client C
INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
WHERE AC.Agent_ID = #Agent_ID
ORDER BY C.Client_ID ASC
DECLARE #MaxClientCreateDate datetime
SELECT #MaxClientCreateDate = MAX(Create_Date)
FROM realforms.dbo.Client C
PRINT 'Max Create Date:'
PRINT #MaxClientCreateDate
DECLARE #ClientCreateDate datetime
SET #ClientCreateDate = CAST('01-01-2000' AS datetime)
OPEN Client_Cursor;
FETCH NEXT FROM Client_Cursor
INTO #Client_ID
-- loop through each 2010 client
WHILE (1 < 2)
BEGIN
DECLARE #myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER)
BEGIN TRY
PRINT 'Client ID:'
PRINT #Client_ID
PRINT 'Agent ID:'
PRINT #Agent_ID
INSERT INTO realforms_2011.dbo.Client (Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,[Year],IsFavorite) OUTPUT inserted.Client_GUID INTO #myNewPKTable
SELECT c.Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,2010,0
FROM realforms.dbo.Client C
INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
WHERE AC.Agent_ID = #Agent_ID AND C.Client_ID = #Client_ID
SELECT #Client_GUID = myNewPK FROM #myNewPKTable
PRINT 'Client GUID Inserted: '
PRINT #Client_GUID
INSERT INTO realforms_2011.dbo.Client_Bucket_Client (Client_Bucket_GUID, Client_GUID, Client_ID, Client_Bucket_ID, [Year])
VALUES (#Client_Bucket_GUID, #Client_GUID, #Client_ID, #Client_Bucket_ID, 2010)
PRINT 'Client Bucket GUID: '
PRINT #Client_Bucket_GUID
PRINT 'Client ID Inserted: '
PRINT #Client_ID
SELECT #ClientCreateDate = CAST(Create_Date as datetime)
FROM realforms.dbo.Client C
INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
WHERE AC.Agent_ID = #Agent_ID AND C.Client_ID = #Client_ID
PRINT #ClientCreateDate
END TRY
BEGIN CATCH
PRINT 'Error:'
PRINT ERROR_MESSAGE()
PRINT 'Last Client GUID Inserted: '
PRINT #Client_GUID
PRINT 'Last Client ID: '
PRINT #Client_ID
END CATCH
IF ##ERROR != 0 GOTO ERR_HANDLER
IF (#ClientCreateDate >= #MaxClientCreateDate)
BREAK
FETCH NEXT FROM Client_Cursor
INTO #Client_ID;
END;
CLOSE Client_Cursor;
DEALLOCATE Client_Cursor;
IF (#AgentCounter >= #MaxAgentCount)
BREAK
FETCH NEXT FROM Agent_Cursor
INTO #Agent_GUID, #Agent_ID;
END;
CLOSE Agent_Cursor;
DEALLOCATE Agent_Cursor;
ERR_HANDLER: PRINT 'ERROR'
END
It breaks on #Client_ID

You can nest fetch_status since the last statement of each loop is fetch next.

Related

SQL SERVER 2016 -CAN execute SP with parameters inside a Function?

I have an SP which brings a table with some fields and subtracts the results to another table, I tried to do this as a function but as you know you can not use DML sentences in a function so I created this SP:
CREATE OR ALTER PROCEDURE SP_Integraciones_AsignarLotesLineas
#Cantidad numeric, #producto nvarchar(max), #bodega nvarchar(max)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE #temp as table(idLoteT nvarchar(max), CantidadT numeric, FechaT date)
DECLARE #loteAc nvarchar(Max), #CantidadAc numeric, #restante numeric , #Cont numeric, #fechaAc date, #resultado nvarchar(max)
SET #Cont = #Cantidad
DECLARE CursoIns CURSOR SCROLL
FOR SELECT IdLote, CONVERT(NUMERIC,cantidad), Fecha
FROM tblintegraciones_lotes
WHERE idproducto = #producto
AND Bodega = #bodega
AND cantidad > '0.0'
ORDER BY fecha ASC
OPEN CursoIns
FETCH CursoIns INTO #loteAc, #CantidadAc, #fechaAc
WHILE( #Cont > 0 AND ##FETCH_STATUS = 0 )
BEGIN
IF( #CantidadAc >= #Cont )
BEGIN
SET #restante = #CantidadAc- #Cont
INSERT INTO #temp(
idLoteT, CantidadT, FechaT
)VALUES(
#loteAc, #Cont, #fechaAc
)
UPDATE tblintegraciones_lotes SET Cantidad = #restante WHERE idProducto = #producto AND IdLote = #loteAc
SET #Cont = #cont - #CantidadAc
END
ELSE
BEGIN
SET #Cont = #Cont - #CantidadAc
SET #restante = #Cont - #CantidadAc
INSERT INTO #temp(
idLoteT, CantidadT, FechaT
)VALUES(
#loteAc, #CantidadAc, #fechaAc
)
UPDATE tblintegraciones_lotes SET Cantidad = 0 WHERE idProducto = #producto AND IdLote = #loteAc
END
FETCH CursoIns INTO #loteAc, #CantidadAc, #fechaAc
END
CLOSE CursoIns;
DEALLOCATE CursoIns;
SELECT * FROM #temp
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK
DECLARE #DescripcionError AS nvarchar(max)
SET #DescripcionError = ERROR_MESSAGE()
RAISERROR (#DescripcionError, 18, 1, 'Inventario - lotes - Integraciones', 5)
END CATCH
END
GO
but the problem is that I must run this in a select since I need that query parcing to JSON, so there should be 2 solutions:
Execute this SP in a select sentence
Create some function that calls the SP.
Can you help me how can I execute this SP in a function or find the best soluction?
Here the Query that I need execute this:
(SELECT CASE
WHEN MFAC.codigo IN ('ME-14009',
'ME-14010',
'ME-14011') THEN 'IMP-BOLSAP'
ELSE MFAC.codigo
END AS ItemCode,
REPLACE(MFAC.cantidad, ',', '.') AS Quantity,
CASE WHEN MFAC.codigo LIKE '%PV%' THEN MFAC.valor ELSE null END as Price,
REPLACE(MFAC.descuento, ',', '.') AS DiscountPercent,
CASE
WHEN MFAC.codbodega = 'PV-PER' THEN 'PV-DQU'
ELSE MFAC.codbodega
END AS WarehouseCode,
#OcrCode3 AS CostingCode3,
#OcrCode3 AS COGSCostingCode3
FOR JSON PATH
) DocumentLines

SQL Server if statement does not execute as expected

I am trying to use the following stored procedure but there are some instances WHERE only the incremental happens AND the code does not run. What I need is that, when the program enters the IF statement, either it should run both the statements or None.
Stored procedure goes like this:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spflpunch]
AS
BEGIN
DECLARE #id NUMERIC(18,0)
DECLARE #studname NVARCHAR(50)
DECLARE #punchtime DATETIME
DECLARE #samedaycount NUMERIC(2)
SELECT #id = (MAX(lastid)) FROM [smartswype].[dbo].[read]
PRINT #id
SELECT #studname = studname
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE id =#id
PRINT #studname
SELECT #punchtime = punchtime
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE id = #id
PRINT #punchtime
--SELECT #punchvarchar = CONVERT(VARCHAR(10),#punchtime, 103) + ' ' + CONVERT(VARCHAR(5), #punchtime, 14)
IF #id = (SELECT MAX(id) FROM [SSWYPE_WEBDB].[dbo].[attdview])
BEGIN
SELECT #samedaycount = COUNT(*)
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE (studname = #studname
AND CONVERT(DATE, punchtime) = CONVERT(DATE, #punchtime)) -- If firstpunch = 1 then it is the first punch
PRINT #samedaycount
IF #samedaycount =1
BEGIN
INSERT INTO [smartswype].[dbo].[firstlastpunch] ([studname], [DATE], [punch1], [punch2])
VALUES(#studname, CONVERT(DATE, #punchtime), #punchtime, NULL);
UPDATE [smartswype].[dbo].[read]
SET lastid = #id + 1;
END
ELSE IF (#samedaycount > 1)
BEGIN
UPDATE [smartswype].[dbo].[firstlastpunch]
SET punch2 = #punchtime
WHERE (studname = #studname AND DATE = CONVERT(DATE, #punchtime));
UPDATE [smartswype].[dbo].[read]
SET lastid = #id + 1;
END
END
END
If you want to ensure that both or none of the statements run, you should wrap the contents of the if statement in a transaction.
By wrapping it in a transaction, you can ensure that if one statement fails, that the other statement will not run.
Here is a link to the docs on transactions in SQL Server
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/commit-transaction-transact-sql

Why am I always getting "The multi-part identifier Column could not be bound"?

I'm new to SQL Server and I want to compare a value from one column with another value from another column. The flow was like this:
if value from table1 != value from table 2
continue
...but how do I just compare the value from the columns.
If I do SELECT #variable=COLUMN FROM TABLE and IF #variable1!=#variable2, it is not working.
I'm using SQL Server 2012.
Here's the query:
SELECT #AgentID=AGENTID
,#CreateTime1=CREATEDATE
FROM AGENT
SELECT #Agid=AgentNo
,#CreateTime2=[Join Date]
,#AccCount2=AgentID
FROM LOCALDB_AGENT
IF #CreateTime1>#CreateTime2
BEGIN
IF #AgentID!=#Agid
BEGIN
INSERT INTO LOCALDB_AGENT (AgentName,AgentID,AgentNo,Email,[Join Date],CreatedDate)
SELECT [FIRSTNAME],[AGENTID],[AGENTID],[EMAIL],CREATEDATE,GetDate() AS CreatedDate
FROM AGENT
WHERE #AgentID!=#Agid
SELECT #AccCount2=COUNT(*)
FROM LOCALDB_AGENT
WHERE [Status]='ACTIVE' AND CreatedDate=Getdate()
SET #msg = 'New Record to DMTM' + ' = ' + #AccCount2 + char(10)
PRINT #msg
END
ELSE
BEGIN
PRINT 'Data Already Exist'
END
END
Option1:
IF (SELECT 1) != (SELECT 2)
BEGIN
PRINT 'CONTINUE'
END
Else you can use a variable to store the column value and then compare the variables.
Option2:
DECLARE #Variable1 INT
DECLARE #Variable2 INT
SELECT #Variable1 = 1
SELECT #Variable2 = 2
IF #Variable1 != #Variable2
BEGIN
PRINT 'CONTINUE'
END
REPLACE the SELECT Statement with your query

Finding a user account in a SQL Server database?

Is there a way to find a particular user account in a database on a SQL Server?
Typically you would add an account to the SQL Server, at which point you can also map the user to multiple databases on that server. As long as no one does anything bad, you can return to the account properties on the server as see the databases the account was mapped to.
However, this linkage can be easily broken, where an account exists in a database, but it does not show up as mapped to that database at the server level. Also, you cannot create an account on the server if it already exists in one of the databases, this is the situation I'm in.
There are 100's of databases and I need to find the one that this users account is in. As far as I know sys.database_principals us unique to each database. Is it possible to do a cross database search for an account and return the database(s) that it exists in?
Here are some helper queries.
declare #returnValue int
EXEC #returnValue = sp_change_users_login 'Update_One', 'SXAUtil', 'SXAUtil'
print '/#returnValue/'
print #returnValue
print ''
select * from master..syslogins where name='MyUser001'
select * from [MyDatabase001]..sysusers where name='MyUser001'
select 1 as 'Match??' , mastSysLogin.sid as mastSysLogin_Sid, localSysLogin.sid as localSysLogin_Sid, mastSysLogin.name as mastSysLogin_Name , localSysLogin.name as localSysLogin_Name from master..syslogins mastSysLogin join [MyDatabase001]..sysusers localSysLogin on mastSysLogin.sid = localSysLogin.sid
where mastSysLogin.name='MyUser001'
go
This procedure is being deprecated I think, but researching it will show some "missing link" informaiton.
Use MyDatabase001
GO
declare #returnValue int
EXEC #returnValue = sp_change_users_login 'Update_One', 'MyUser001', 'MyUser001'
print '/#returnValue/'
print #returnValue
print ''
Below is a script I wrote to add users to logins and as dbusers and map to some roles.
It uses SQLCMD Mode. But it is a "over the years" effort as I tried to write code to create users , and it wouldn't throw errors if the user was already added.
/*
--SqlCmd Notes:
--Remove comments and space between ":" and "setvar" to run in sqlcmd mode.
--!!! Checked in code MUST *recomment out* the setvars below !!! (Putting a space between the ":" and the "setvar" is sufficient)
-- (This is not preferred behavior, the issue has been reported at http://connect.microsoft.com/SQLServer/feedback/details/382007/in-sqlcmd-scripts-setvar-should-have-a-lower-precedence-than-command-line-variable-assignments )
: setvar ErrorOutputFileFromCommandLine "c:\wuwutemp\sqlcommmanderrorfile.txt"
: setvar DBNAME "MyDatabaseName"
: setvar DBUSERNAME "MyDomain\someDomainUserThatExists"
*/
Use [$(DBNAME)]
GO
:Error $(ErrorOutputFileFromCommandLine)
declare #databaseName varchar(64)
select #databaseName = db_name()
print '/#databaseName/'
print #databaseName
print ''
set nocount on
declare #CONST_DB_DATAREADER_ROLE varchar(64)
select #CONST_DB_DATAREADER_ROLE = 'db_datareader'
declare #CONST_DB_BACKUPOPERATOR_ROLE varchar(64)
select #CONST_DB_BACKUPOPERATOR_ROLE = 'db_backupoperator'
declare #UserNameHolder table ( IdentityID int identity(101,1) , DatabaseName varchar(128) , LoginName varchar(256) , MassagedLoginName varchar(264) , RoleName varchar(64) not null , AlreadyProcessed bit default 0 not null )
INSERT INTO #UserNameHolder ( DatabaseName , LoginName , RoleName ) values ( '$(DBNAME)' , '$(DBUSERNAME)' , #CONST_DB_DATAREADER_ROLE )
--INSERT INTO #UserNameHolder ( DatabaseName , LoginName , RoleName ) values ( '$(DBNAME)' , '$(DBUSERNAME)' , #CONST_DB_BACKUPOPERATOR_ROLE )
/* Below this line is "common logic code" */
Update #UserNameHolder Set MassagedLoginName = LoginName
/*
sp_grantlogin does NOT like brackets around a domain/user
example : EXEC sp_grantlogin #loginame = N'[MyDomain\MyUser]'
The "massaging" below is a work around to this issue
*/
Update #UserNameHolder Set MassagedLoginName = RIGHT(MassagedLoginName , LEN(MassagedLoginName) -1 ) where LEN(MassagedLoginName)>0 AND LEFT( MassagedLoginName,1)='['
Update #UserNameHolder Set MassagedLoginName = LEFT( MassagedLoginName , LEN(MassagedLoginName) -1 ) where LEN(MassagedLoginName)>0 AND RIGHT(MassagedLoginName,1)=']'
/* Use a iffy rule to figure out NT Names */
--Update #UserNameHolder Set IsNTName = 1 where LEN(LoginName)>0 AND LEFT( LoginName,1)='[' AND RIGHT(LoginName,1)=']'
-- public is built in, do not process it
Update #UserNameHolder Set AlreadyProcessed = 1 where UPPER(LoginName) = UPPER('public')
select * from #UserNameHolder
declare #CurrentIdentityID int
declare #CurrentLoginName varchar(256)
declare #CurrentMassagedLoginName varchar(256)
declare #CurrentDatabaseName varchar(64)
--declare #CurrentIsNTName bit
declare #CurrentRoleName varchar(64)
declare #sp_grantdbaccess_return_value_total int
select #sp_grantdbaccess_return_value_total = 0
declare #sp_addrolemember_return_value_total int
select #sp_addrolemember_return_value_total = 0
while exists (select null from #UserNameHolder where AlreadyProcessed = 0)
begin
select #CurrentIdentityID = (select top 1 IdentityID from #UserNameHolder where AlreadyProcessed = 0)
print '#CurrentIdentityID'
print #CurrentIdentityID
print ''
select #CurrentLoginName = ( select top 1 LoginName from #UserNameHolder where IdentityID = #CurrentIdentityID )
select #CurrentMassagedLoginName = ( select top 1 MassagedLoginName from #UserNameHolder where IdentityID = #CurrentIdentityID )
select #CurrentDatabaseName = ( select top 1 DatabaseName from #UserNameHolder where IdentityID = #CurrentIdentityID )
--select #CurrentIsNTName = ( select top 1 IsNTName from #UserNameHolder where IdentityID = #CurrentIdentityID )
select #CurrentRoleName = ( select top 1 RoleName from #UserNameHolder where IdentityID = #CurrentIdentityID )
print '#CurrentLoginName'
print #CurrentLoginName
print ''
print '#CurrentMassagedLoginName'
print #CurrentMassagedLoginName
print ''
print '#CurrentDatabaseName'
print #CurrentDatabaseName
print ''
--print '#CurrentIsNTName'
--print #CurrentIsNTName
--print ''
print '#CurrentRoleName'
print #CurrentRoleName
print ''
if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */
begin
-- select name, loginname from master.dbo.syslogins where loginname = #currentLoginName and isntname = 1)
if not exists (select null from master.dbo.syslogins where UPPER(loginname) = UPPER(#CurrentLoginName) ) -- and isntname = 1)
begin
print 'About to execute sp_grantlogin for user:'
print #CurrentMassagedLoginName
EXEC sp_grantlogin #loginame = #CurrentMassagedLoginName
print ''
print ''
print 'About to execute sp_defaultdb for user:'
print #CurrentMassagedLoginName
EXEC sp_defaultdb #loginame = #CurrentMassagedLoginName , #defdb = #CurrentDatabaseName
print ''
print ''
end
else
begin
print 'NOT EXECUTED : sp_grantlogin'
print 'NOT EXECUTED : sp_defaultdb'
end
end
----------------------------------------
declare #sp_grantdbaccess_return_value int
declare #sp_change_users_login_return_value int
declare #needToRunThisIteration bit
select #needToRunThisIteration = 0
-- declare #currentLoginName varchar(64)
if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */
begin
if not exists
(
select * from master.dbo.syslogins ml inner join dbo.sysusers
su on ml.sid = su.sid where
su.uid < 6382
and
UPPER(ml.name) = UPPER(#CurrentMassagedLoginName)
)
begin
if not exists
(
/* NOTE, this database name variable must be updated if copying/pasting 'common logic code' between database deployments (NEED_TO_REPLACE_A_VALUE) */
select * from master.dbo.syslogins ml Where
UPPER(ml.name) = UPPER(#CurrentMassagedLoginName)
and UPPER(ml.dbname) = UPPER('$(DBNAME)')
)
begin
select #needToRunThisIteration = 1
end
end
if not exists
(
/* NOTE, this database name variable must be updated if copying/pasting 'common logic code' between database deployments (NEED_TO_REPLACE_A_VALUE) */
select * FROM [$(DBNAME)]..sysusers su Where
UPPER(su.name) = UPPER(#CurrentMassagedLoginName)
)
begin
select #needToRunThisIteration = 1
end
/*
Debug
select dbname , loginname , * from master.dbo.syslogins ml where dbname != 'master' order by 1 , 2
select * FROM TPA2Report..sysusers su
*/
declare #stringNameMatchesButNotSid bit
select #stringNameMatchesButNotSid = 0
IF EXISTS (
SELECT dbUsers.name as NameToFix , *
FROM sys.sysusers dbUsers
join sys.syslogins sqlServerLogins on UPPER(dbUsers.name) = UPPER(sqlServerLogins.name)
WHERE dbUsers.sid != sqlServerLogins.sid
and UPPER(dbUsers.name) = UPPER(#CurrentMassagedLoginName)
)
begin
select #stringNameMatchesButNotSid = 1
end
if (#needToRunThisIteration!=0)
begin
if #stringNameMatchesButNotSid = 0
begin
print 'About to execute sp_grantdbaccess for user:'
print #CurrentMassagedLoginName
exec #sp_grantdbaccess_return_value = sp_grantdbaccess #CurrentMassagedLoginName
print ''
print '#sp_grantdbaccess_return_value'
print #sp_grantdbaccess_return_value
print ''
select #sp_grantdbaccess_return_value_total = #sp_grantdbaccess_return_value_total + #sp_grantdbaccess_return_value
end
else
begin
/* There is a mismatched "sid" issue, but with the same names. This will address the issue. */
print 'About to execute sp_change_users_login for user:'
print #CurrentMassagedLoginName
EXEC #sp_change_users_login_return_value = sp_change_users_login #Action='update_one', #UserNamePattern=#CurrentMassagedLoginName,#LoginName=#CurrentMassagedLoginName;
print ''
print '#sp_change_users_login_return_value'
print #sp_change_users_login_return_value
print ''
end
end
end
-------------------------------------------------------
declare #sp_addrolemember_return_value int
if(1=1) /* 1=1 is helpful while debugging, set to 1=2 to exclude */
begin
if not exists
(
SELECT null --, role_principal_id, member_principal_id, princ1.name AS
role_name, princ2.name As member_name
FROM sys.database_role_members AS S LEFT JOIN sys.database_principals AS
princ1 ON S.role_principal_id = princ1.principal_id AND princ1.type = 'R'
LEFT JOIN sys.database_principals AS princ2 ON S.member_principal_id =
princ2.principal_id AND princ2.type IN ('S', 'U')
WHERE princ1.name = #CurrentRoleName and UPPER(princ2.name) = UPPER(#CurrentMassagedLoginName)
)
begin
print 'About to execute sp_grantdbaccess for user:'
print #CurrentMassagedLoginName
print 'For the role:'
print #CurrentRoleName
exec #sp_addrolemember_return_value = sp_addrolemember #CurrentRoleName, #CurrentMassagedLoginName
print ''
print '#sp_addrolemember_return_value'
print #sp_addrolemember_return_value
print ''
select #sp_addrolemember_return_value_total = #sp_addrolemember_return_value_total + #sp_addrolemember_return_value
end
end
Update #UserNameHolder Set AlreadyProcessed = 1 Where IdentityID = #CurrentIdentityID
end
print '/#sp_grantdbaccess_return_value_total/'
print #sp_grantdbaccess_return_value_total
print '/#sp_addrolemember_return_value_total/'
print #sp_addrolemember_return_value_total
GO

Procedure Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)

The stored proc is failing at below location,Thanks, for all your help.
--Insert MSOrg Information
DECLARE #PersonnelNumber int,
#MSOrg varchar(255)
DECLARE csr CURSOR FAST_FORWARD FOR
SELECT PersonnelNumber FROM Person
OPEN csr
FETCH NEXT FROM csr
INTO #PersonnelNumber
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC GetMSOrg #PersonnelNumber, #MSOrg out
INSERT INTO PersonSubject (
PersonnelNumber
,SubjectID
,SubjectValue
,Created
,Updated
)
SELECT #PersonnelNumber
,SubjectID
,#MSOrg
,getDate()
,getDate()
FROM Subject
WHERE DisplayName = 'MS Org'
FETCH NEXT FROM csr
INTO #PersonnelNumber
END
CLOSE csr
DEALLOCATE csr
Below is the stored prc defination GetMSOrg and fails at third condition
CREATE PROCEDURE [dbo].[GetMSOrg]
(
#PersonnelNumber int
,#OrgTerm varchar(200) out
)
AS
DECLARE #MDRTermID int
,#ReportsToPersonnelNbr int
--Check to see if we have reached the top of the chart
SELECT #ReportsToPersonnelNbr = ReportsToPersonnelNbr
FROM ReportsTo
WHERE PersonnelNumber = #PersonnelNumber
IF (#ReportsToPersonnelNbr IS NULL) --Reached the Top of the Org Ladder
BEGIN
SET #OrgTerm = 'Non-standard rollup'
END
ELSE IF (#PersonnelNumber IN (SELECT PersonnelNumber FROM OrgTermMap))
BEGIN
SELECT #OrgTerm = s.Term
FROM OrgTermMap tm
JOIN Taxonomy..StaticHierarchy s ON tm.OrgTermID = s.TermID
WHERE tm.PersonnelNumber = #PersonnelNumber
END
ELSE
BEGIN
SELECT #MDRTermID = tm.OrgTermID
FROM ReportsTo r
JOIN OrgTermMap tm ON r.ReportsToPersonnelNbr = tm.PersonnelNumber
WHERE r.PersonnelNumber = #PersonnelNumber
IF (#MDRTermID IS NULL)
BEGIN
EXEC GetMSOrg #ReportsToPersonnelNbr, #OrgTerm out
END
ELSE
BEGIN
SELECT #OrgTerm = Term
FROM Taxonomy..StaticHierarchy
WHERE VocabID = 118
AND TermID = #MDRTermID
END
END
GO
Each call to EXEC GetMSOrg keeps progressing along the query
SELECT #ReportsToPersonnelNbr = ReportsToPersonnelNbr
FROM ReportsTo
WHERE PersonnelNumber = #PersonnelNumber
And there is an exit clause when PersonnelNumber no longer reports to anyone.
Therefore the only logical conclusion is that you have a cyclical person->reportsto->..->person. This could even be on a single record.
This query will find loops within the reportsto records:
declare #PersonnelNumber int
set #PersonnelNumber = 10
;with CTE as (
select 1 Level,
convert(varchar(max),#PersonnelNumber) Seed,
'>>' + convert(varchar(max),#PersonnelNumber) + '>>' Path
union all
SELECT Level+1,
convert(varchar(max),ReportsToPersonnelNbr),
Path + convert(varchar(max),ReportsToPersonnelNbr) + '>>'
FROM ReportsTo
join CTE on CTE.Seed = ReportsTo.PersonnelNumber
where Level < 40
)
select *
from CTE
where Len(Replace(Path, '>' + convert(varchar(max),Seed) + '>', ''))
= LEN(Path) - Len('>' + convert(varchar(max),Seed) + '>') * 2

Resources